Can fire with keyboard

This commit is contained in:
Pierre HUBERT 2022-10-15 15:53:27 +02:00
parent 454dff923b
commit acd13af227
8 changed files with 63 additions and 25 deletions

View File

@ -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<B: Backend>(
.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<B: Backend>(
..Default::default()
};
set_boats_layout::SetBoatsLayoutScreen::new(&rules)
set_boats_layout_screen::SetBoatsLayoutScreen::new(&rules)
.show(terminal)?
.as_string()
}

View File

@ -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;

View File

@ -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<String>,
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::<Vec<_>>(),
};
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

View File

@ -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)]

View File

@ -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};