From acd13af227628bb169124ead9748e131bcea359f Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Sat, 15 Oct 2022 15:53:27 +0200 Subject: [PATCH] Can fire with keyboard --- rust/cli_player/src/main.rs | 10 +-- .../src/ui_screens/configure_game_rules.rs | 2 +- ...irm_dialog.rs => confirm_dialog_screen.rs} | 0 rust/cli_player/src/ui_screens/game_screen.rs | 66 +++++++++++++++---- rust/cli_player/src/ui_screens/mod.rs | 8 +-- ..._bot_type.rs => select_bot_type_screen.rs} | 0 ...lay_mode.rs => select_play_mode_screen.rs} | 0 ...s_layout.rs => set_boats_layout_screen.rs} | 2 +- 8 files changed, 63 insertions(+), 25 deletions(-) rename rust/cli_player/src/ui_screens/{confirm_dialog.rs => confirm_dialog_screen.rs} (100%) rename rust/cli_player/src/ui_screens/{select_bot_type.rs => select_bot_type_screen.rs} (100%) rename rust/cli_player/src/ui_screens/{select_play_mode.rs => select_play_mode_screen.rs} (100%) rename rust/cli_player/src/ui_screens/{set_boats_layout.rs => set_boats_layout_screen.rs} (99%) diff --git a/rust/cli_player/src/main.rs b/rust/cli_player/src/main.rs index 808280c..91e84da 100644 --- a/rust/cli_player/src/main.rs +++ b/rust/cli_player/src/main.rs @@ -18,7 +18,7 @@ use cli_player::server::start_server_if_missing; use cli_player::ui_screens::configure_game_rules::GameRulesConfigurationScreen; use cli_player::ui_screens::game_screen::GameScreen; use cli_player::ui_screens::popup_screen::PopupScreen; -use cli_player::ui_screens::select_play_mode::{SelectPlayModeResult, SelectPlayModeScreen}; +use cli_player::ui_screens::select_play_mode_screen::{SelectPlayModeResult, SelectPlayModeScreen}; use cli_player::ui_screens::*; use sea_battle_backend::data::GameRules; use sea_battle_backend::human_player_ws::ServerMessage; @@ -37,14 +37,14 @@ async fn run_dev( .show(terminal)? .as_string(), TestDevScreen::Confirm => { - confirm_dialog::ConfirmDialogScreen::new("Do you really want to quit game?") + confirm_dialog_screen::ConfirmDialogScreen::new("Do you really want to quit game?") .show(terminal)? .as_string() } - TestDevScreen::SelectBotType => select_bot_type::SelectBotTypeScreen::default() + TestDevScreen::SelectBotType => select_bot_type_screen::SelectBotTypeScreen::default() .show(terminal)? .as_string(), - TestDevScreen::SelectPlayMode => select_play_mode::SelectPlayModeScreen::default() + TestDevScreen::SelectPlayMode => select_play_mode_screen::SelectPlayModeScreen::default() .show(terminal)? .as_string(), TestDevScreen::SetBoatsLayout => { @@ -53,7 +53,7 @@ async fn run_dev( ..Default::default() }; - set_boats_layout::SetBoatsLayoutScreen::new(&rules) + set_boats_layout_screen::SetBoatsLayoutScreen::new(&rules) .show(terminal)? .as_string() } diff --git a/rust/cli_player/src/ui_screens/configure_game_rules.rs b/rust/cli_player/src/ui_screens/configure_game_rules.rs index e4416ac..6e5928b 100644 --- a/rust/cli_player/src/ui_screens/configure_game_rules.rs +++ b/rust/cli_player/src/ui_screens/configure_game_rules.rs @@ -14,7 +14,7 @@ use tui::{Frame, Terminal}; use sea_battle_backend::data::GameRules; use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE}; -use crate::ui_screens::select_bot_type::SelectBotTypeScreen; +use crate::ui_screens::select_bot_type_screen::SelectBotTypeScreen; use crate::ui_screens::utils::centered_rect_size; use crate::ui_screens::ScreenResult; use crate::ui_widgets::button_widget::ButtonWidget; diff --git a/rust/cli_player/src/ui_screens/confirm_dialog.rs b/rust/cli_player/src/ui_screens/confirm_dialog_screen.rs similarity index 100% rename from rust/cli_player/src/ui_screens/confirm_dialog.rs rename to rust/cli_player/src/ui_screens/confirm_dialog_screen.rs diff --git a/rust/cli_player/src/ui_screens/game_screen.rs b/rust/cli_player/src/ui_screens/game_screen.rs index ea355bf..4a7faaf 100644 --- a/rust/cli_player/src/ui_screens/game_screen.rs +++ b/rust/cli_player/src/ui_screens/game_screen.rs @@ -3,20 +3,21 @@ use std::time::{Duration, Instant}; use crossterm::event; use crossterm::event::{Event, KeyCode}; -use sea_battle_backend::data::{CurrentGameMapStatus, CurrentGameStatus}; -use sea_battle_backend::human_player_ws::{ClientMessage, ServerMessage}; -use sea_battle_backend::utils::Res; use tui::backend::Backend; use tui::layout::{Constraint, Direction, Layout}; use tui::style::Color; use tui::widgets::Paragraph; use tui::{Frame, Terminal}; +use sea_battle_backend::data::{Coordinates, CurrentGameMapStatus, CurrentGameStatus}; +use sea_battle_backend::human_player_ws::{ClientMessage, ServerMessage}; +use sea_battle_backend::utils::Res; + use crate::client::Client; use crate::constants::*; -use crate::ui_screens::confirm_dialog::confirm; +use crate::ui_screens::confirm_dialog_screen::confirm; use crate::ui_screens::popup_screen::PopupScreen; -use crate::ui_screens::set_boats_layout::SetBoatsLayoutScreen; +use crate::ui_screens::set_boats_layout_screen::SetBoatsLayoutScreen; use crate::ui_screens::utils::{centered_rect_size, centered_text}; use crate::ui_screens::ScreenResult; use crate::ui_widgets::game_map_widget::{ColoredCells, GameMapWidget}; @@ -54,7 +55,8 @@ pub struct GameScreen { client: Client, status: GameStatus, opponent_name: Option, - game_status: CurrentGameStatus, + game: CurrentGameStatus, + curr_shoot_position: Coordinates, } impl GameScreen { @@ -63,7 +65,8 @@ impl GameScreen { client, status: GameStatus::Pending, opponent_name: None, - game_status: Default::default(), + game: Default::default(), + curr_shoot_position: Coordinates::new(0, 0), } } @@ -80,6 +83,8 @@ impl GameScreen { // Handle terminal events if crossterm::event::poll(timeout)? { if let Event::Key(key) = event::read()? { + let mut new_shoot_pos = self.curr_shoot_position; + match key.code { // Leave game KeyCode::Char('q') @@ -87,8 +92,28 @@ impl GameScreen { { return Ok(ScreenResult::Canceled); } + + // Move shoot cursor + KeyCode::Left if self.can_fire() => new_shoot_pos = new_shoot_pos.add_x(-1), + KeyCode::Right if self.can_fire() => new_shoot_pos = new_shoot_pos.add_x(1), + KeyCode::Up if self.can_fire() => new_shoot_pos = new_shoot_pos.add_y(-1), + KeyCode::Down if self.can_fire() => new_shoot_pos = new_shoot_pos.add_y(1), + + // Shoot + KeyCode::Enter if self.can_fire() => { + if self.game.can_fire_at_location(self.curr_shoot_position) { + self.client.send_message(&ClientMessage::Fire { + location: self.curr_shoot_position, + }).await?; + } + } + _ => {} } + + if new_shoot_pos.is_valid(&self.game.rules) { + self.curr_shoot_position = new_shoot_pos; + } } } @@ -137,12 +162,12 @@ impl GameScreen { ServerMessage::OpponentMustFire { status } => { self.status = GameStatus::OpponentMustFire; - self.game_status = status; + self.game = status; } ServerMessage::RequestFire { status } => { self.status = GameStatus::MustFire; - self.game_status = status; + self.game = status; } ServerMessage::FireResult { .. } => {} @@ -172,7 +197,20 @@ impl GameScreen { self.opponent_name.as_deref().unwrap_or("opponent") } - fn player_map(&self, map: &CurrentGameMapStatus) -> GameMapWidget { + fn player_map(&self, map: &CurrentGameMapStatus, opponent_map: bool) -> GameMapWidget { + let mut map_widget = GameMapWidget::new(&self.game.rules); + + // Current shoot position + if opponent_map { + map_widget = map_widget.add_colored_cells(ColoredCells { + color: match self.game.can_fire_at_location(self.curr_shoot_position) { + true => Color::Green, + false => Color::LightYellow, + }, + cells: vec![self.curr_shoot_position], + }); + } + // Sunk boats let sunk_boats = ColoredCells { color: Color::Red, @@ -206,7 +244,7 @@ impl GameScreen { .collect::>(), }; - GameMapWidget::new(&self.game_status.rules) + map_widget .add_colored_cells(sunk_boats) .add_colored_cells(touched_areas) .add_colored_cells(failed_strikes) @@ -227,16 +265,16 @@ impl GameScreen { // Draw main ui (default play UI) let player_map = self - .player_map(&self.game_status.your_map) + .player_map(&self.game.your_map, false) .set_title("YOUR map"); let mut opponent_map = self - .player_map(&self.game_status.opponent_map) + .player_map(&self.game.opponent_map, true) .set_title(self.opponent_name()); if self.can_fire() { opponent_map = opponent_map - .set_legend("Use arrows + enter\nor click on the place\nwhere you want\nto shoot"); + .set_legend("Use arrows + Enter\nor click on the place\nwhere you want\nto shoot"); } // Show both maps if there is enough room on the screen diff --git a/rust/cli_player/src/ui_screens/mod.rs b/rust/cli_player/src/ui_screens/mod.rs index 88e6690..906f190 100644 --- a/rust/cli_player/src/ui_screens/mod.rs +++ b/rust/cli_player/src/ui_screens/mod.rs @@ -1,13 +1,13 @@ use std::fmt::Debug; pub mod configure_game_rules; -pub mod confirm_dialog; +pub mod confirm_dialog_screen; pub mod game_screen; pub mod input_screen; pub mod popup_screen; -pub mod select_bot_type; -pub mod select_play_mode; -pub mod set_boats_layout; +pub mod select_bot_type_screen; +pub mod select_play_mode_screen; +pub mod set_boats_layout_screen; pub mod utils; #[derive(Debug)] diff --git a/rust/cli_player/src/ui_screens/select_bot_type.rs b/rust/cli_player/src/ui_screens/select_bot_type_screen.rs similarity index 100% rename from rust/cli_player/src/ui_screens/select_bot_type.rs rename to rust/cli_player/src/ui_screens/select_bot_type_screen.rs diff --git a/rust/cli_player/src/ui_screens/select_play_mode.rs b/rust/cli_player/src/ui_screens/select_play_mode_screen.rs similarity index 100% rename from rust/cli_player/src/ui_screens/select_play_mode.rs rename to rust/cli_player/src/ui_screens/select_play_mode_screen.rs diff --git a/rust/cli_player/src/ui_screens/set_boats_layout.rs b/rust/cli_player/src/ui_screens/set_boats_layout_screen.rs similarity index 99% rename from rust/cli_player/src/ui_screens/set_boats_layout.rs rename to rust/cli_player/src/ui_screens/set_boats_layout_screen.rs index 648b81f..3558050 100644 --- a/rust/cli_player/src/ui_screens/set_boats_layout.rs +++ b/rust/cli_player/src/ui_screens/set_boats_layout_screen.rs @@ -13,7 +13,7 @@ use tui::{Frame, Terminal}; use sea_battle_backend::data::*; use crate::constants::*; -use crate::ui_screens::confirm_dialog::confirm; +use crate::ui_screens::confirm_dialog_screen::confirm; use crate::ui_screens::utils::{centered_rect_size, centered_text}; use crate::ui_screens::ScreenResult; use crate::ui_widgets::game_map_widget::{ColoredCells, GameMapWidget};