From 17a4edf417ceb1403be9c3fec6730d4614ac17f4 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Sun, 2 Oct 2022 19:17:29 +0200 Subject: [PATCH] Improve game rules configuration screen --- rust/cli_player/src/constants.rs | 3 +++ rust/cli_player/src/main.rs | 5 ++-- .../src/ui_screens/configure_game_rules.rs | 11 ++++---- .../src/ui_screens/select_bot_type.rs | 6 ++--- .../src/ui_screens/select_play_mode.rs | 8 +++--- .../src/ui_widgets/button_widget.rs | 3 ++- .../src/ui_widgets/checkbox_widget.rs | 5 ++-- .../src/ui_widgets/text_editor_widget.rs | 12 ++++++--- .../sea_battle_backend/src/data/game_rules.rs | 26 +++++++++++++------ 9 files changed, 51 insertions(+), 28 deletions(-) diff --git a/rust/cli_player/src/constants.rs b/rust/cli_player/src/constants.rs index 09cb3b6..b9afb9e 100644 --- a/rust/cli_player/src/constants.rs +++ b/rust/cli_player/src/constants.rs @@ -1,3 +1,6 @@ use std::time::Duration; +use tui::style::Color; pub const TICK_RATE: Duration = Duration::from_millis(250); + +pub const HIGHLIGHT_COLOR: Color = Color::Green; diff --git a/rust/cli_player/src/main.rs b/rust/cli_player/src/main.rs index 4667b15..c11497f 100644 --- a/rust/cli_player/src/main.rs +++ b/rust/cli_player/src/main.rs @@ -14,13 +14,14 @@ use tui::Terminal; use cli_player::server::start_server_if_missing; use cli_player::ui_screens::*; +use sea_battle_backend::data::GameRules; async fn run_app(terminal: &mut Terminal) -> Result<(), Box> { // Temporary code - let res = select_bot_type::select_bot_type(terminal)?; + let res = configure_game_rules::configure_play_rules(GameRules::default(), terminal)?; // select_bot_type::select_bot_type(terminal)?; Err(io::Error::new( ErrorKind::Other, - format!("configured rules: {:?}", res), + format!("result: {:?}", res), ))?; Ok(()) } 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 ca14f3a..5559f75 100644 --- a/rust/cli_player/src/ui_screens/configure_game_rules.rs +++ b/rust/cli_player/src/ui_screens/configure_game_rules.rs @@ -1,6 +1,5 @@ extern crate num as num_renamed; -use std::cmp::max; use std::io; use std::time::{Duration, Instant}; @@ -64,7 +63,7 @@ pub fn configure_play_rules( // Navigate between fields KeyCode::Up | KeyCode::Left => cursor_pos -= 1, - KeyCode::Down | KeyCode::Right => cursor_pos += 1, + KeyCode::Down | KeyCode::Right | KeyCode::Tab => cursor_pos += 1, // Submit results KeyCode::Enter => { @@ -127,9 +126,11 @@ pub fn configure_play_rules( } // Apply new cursor position - cursor_pos = max(0, cursor_pos); - if let Some(val) = num_renamed::FromPrimitive::from_u64(cursor_pos as u64) { - model.curr_field = val; + model.curr_field = if cursor_pos < 0 { + EditingField::OK + } else { + num_renamed::FromPrimitive::from_u64(cursor_pos as u64) + .unwrap_or(EditingField::MapWidth) } } if last_tick.elapsed() >= TICK_RATE { diff --git a/rust/cli_player/src/ui_screens/select_bot_type.rs b/rust/cli_player/src/ui_screens/select_bot_type.rs index 4372426..9bbf224 100644 --- a/rust/cli_player/src/ui_screens/select_bot_type.rs +++ b/rust/cli_player/src/ui_screens/select_bot_type.rs @@ -4,14 +4,14 @@ use std::time::{Duration, Instant}; use crossterm::event; use crossterm::event::{Event, KeyCode}; use tui::backend::Backend; -use tui::style::{Color, Modifier, Style}; +use tui::style::*; use tui::text::*; use tui::widgets::*; use tui::{Frame, Terminal}; use sea_battle_backend::data::{BotDescription, BotType, PlayConfiguration}; -use crate::constants::TICK_RATE; +use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE}; use crate::ui_screens::utils::centered_rect_size; use crate::ui_screens::ScreenResult; @@ -86,7 +86,7 @@ fn ui(f: &mut Frame, model: &mut SelectPlayModeScreen) { ) .highlight_style( Style::default() - .fg(Color::Green) + .fg(HIGHLIGHT_COLOR) .add_modifier(Modifier::BOLD), ) .highlight_symbol(">> "); diff --git a/rust/cli_player/src/ui_screens/select_play_mode.rs b/rust/cli_player/src/ui_screens/select_play_mode.rs index 78a159b..852e81b 100644 --- a/rust/cli_player/src/ui_screens/select_play_mode.rs +++ b/rust/cli_player/src/ui_screens/select_play_mode.rs @@ -1,14 +1,14 @@ use std::io; use std::time::{Duration, Instant}; -use crate::constants::TICK_RATE; +use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE}; use crate::ui_screens::utils::centered_rect_size; use crossterm::event; use crossterm::event::{Event, KeyCode}; use tui::backend::Backend; -use tui::style::{Color, Modifier, Style}; +use tui::style::*; use tui::text::Text; -use tui::widgets::{Block, Borders, List, ListItem, ListState}; +use tui::widgets::*; use tui::{Frame, Terminal}; #[derive(Debug, Eq, PartialEq, Copy, Clone, Default)] @@ -95,7 +95,7 @@ fn ui(f: &mut Frame, model: &mut SelectPlayModeScreen) { ) .highlight_style( Style::default() - .fg(Color::Green) + .fg(HIGHLIGHT_COLOR) .add_modifier(Modifier::BOLD), ) .highlight_symbol(">> "); diff --git a/rust/cli_player/src/ui_widgets/button_widget.rs b/rust/cli_player/src/ui_widgets/button_widget.rs index 9234ab9..32a3c64 100644 --- a/rust/cli_player/src/ui_widgets/button_widget.rs +++ b/rust/cli_player/src/ui_widgets/button_widget.rs @@ -1,5 +1,6 @@ use std::fmt::Display; +use crate::constants::HIGHLIGHT_COLOR; use tui::buffer::Buffer; use tui::layout::Rect; use tui::style::{Color, Style}; @@ -37,7 +38,7 @@ impl Widget for ButtonWidget { let input = Paragraph::new(label.as_ref()).style(match (self.disabled, self.is_hovered) { (true, _) => Style::default(), (_, false) => Style::default().bg(Color::DarkGray), - (_, true) => Style::default().fg(Color::White).bg(Color::Yellow), + (_, true) => Style::default().fg(Color::White).bg(HIGHLIGHT_COLOR), }); input.render(area, buf); diff --git a/rust/cli_player/src/ui_widgets/checkbox_widget.rs b/rust/cli_player/src/ui_widgets/checkbox_widget.rs index f40e648..821c4f4 100644 --- a/rust/cli_player/src/ui_widgets/checkbox_widget.rs +++ b/rust/cli_player/src/ui_widgets/checkbox_widget.rs @@ -1,7 +1,8 @@ +use crate::constants::HIGHLIGHT_COLOR; use std::fmt::Display; use tui::buffer::Buffer; use tui::layout::Rect; -use tui::style::{Color, Style}; +use tui::style::*; use tui::widgets::*; pub struct CheckboxWidget { @@ -48,7 +49,7 @@ impl Widget for CheckboxWidget { let input = Paragraph::new(paragraph.as_ref()).style(match &self.is_editing { false => Style::default(), - true => Style::default().fg(Color::Yellow), + true => Style::default().fg(HIGHLIGHT_COLOR), }); input.render(area, buf); diff --git a/rust/cli_player/src/ui_widgets/text_editor_widget.rs b/rust/cli_player/src/ui_widgets/text_editor_widget.rs index 6759f11..fea06ec 100644 --- a/rust/cli_player/src/ui_widgets/text_editor_widget.rs +++ b/rust/cli_player/src/ui_widgets/text_editor_widget.rs @@ -1,8 +1,9 @@ use std::fmt::Display; +use crate::constants::HIGHLIGHT_COLOR; use tui::buffer::Buffer; use tui::layout::Rect; -use tui::style::{Color, Style}; +use tui::style::*; use tui::text::*; use tui::widgets::{Block, Borders, Paragraph, Widget}; @@ -37,20 +38,25 @@ impl Widget for TextEditorWidget { self.value.to_string(), match &self.input_mode { InputMode::Normal => Style::default(), - InputMode::Editing => Style::default().fg(Color::Yellow), + InputMode::Editing => Style::default().fg(HIGHLIGHT_COLOR), }, ); let mut spans = vec![span]; + // Add cursor if field is highlighted if self.input_mode == InputMode::Editing { - spans.push(Span::styled(" ", Style::default().bg(Color::Yellow))) + spans.push(Span::styled(" ", Style::default().bg(HIGHLIGHT_COLOR))) } let text = Text::from(Spans::from(spans)); let input = Paragraph::new(text).block( Block::default() .borders(Borders::ALL) + .border_style(match self.input_mode { + InputMode::Normal => Style::default(), + InputMode::Editing => Style::default().fg(HIGHLIGHT_COLOR), + }) .title(self.label.as_ref()), ); diff --git a/rust/sea_battle_backend/src/data/game_rules.rs b/rust/sea_battle_backend/src/data/game_rules.rs index 63ed49d..977d1b2 100644 --- a/rust/sea_battle_backend/src/data/game_rules.rs +++ b/rust/sea_battle_backend/src/data/game_rules.rs @@ -91,18 +91,28 @@ impl GameRules { let mut errors = vec![]; - if self.map_width < config.min_map_width || self.map_width > config.max_map_width { - errors.push("Map width is outside bounds!"); + if self.map_width < config.min_map_width { + errors.push("Map width is too small!"); } - if self.map_height < config.min_map_height || self.map_height > config.max_map_height { - errors.push("Map height is outside bounds!"); + if self.map_width > config.max_map_width { + errors.push("Map width is too big!"); } - if self.boats_list().len() < config.min_boats_number - || self.boats_list().len() > config.max_boats_number - { - errors.push("The number of boats is invalid!"); + if self.map_height < config.min_map_height { + errors.push("Map height is too small!"); + } + + if self.map_height > config.max_map_height { + errors.push("Map height is too big!"); + } + + if self.boats_list().len() < config.min_boats_number { + errors.push("There is not enough boats!"); + } + + if self.boats_list().len() > config.max_boats_number { + errors.push("There are too many boats!"); } for boat in self.boats_list() {