Can change bot type in rules screen
This commit is contained in:
parent
26d5f85c3c
commit
454dff923b
@ -13,7 +13,8 @@ use tui::{Frame, Terminal};
|
|||||||
|
|
||||||
use sea_battle_backend::data::GameRules;
|
use sea_battle_backend::data::GameRules;
|
||||||
|
|
||||||
use crate::constants::TICK_RATE;
|
use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE};
|
||||||
|
use crate::ui_screens::select_bot_type::SelectBotTypeScreen;
|
||||||
use crate::ui_screens::utils::centered_rect_size;
|
use crate::ui_screens::utils::centered_rect_size;
|
||||||
use crate::ui_screens::ScreenResult;
|
use crate::ui_screens::ScreenResult;
|
||||||
use crate::ui_widgets::button_widget::ButtonWidget;
|
use crate::ui_widgets::button_widget::ButtonWidget;
|
||||||
@ -27,6 +28,7 @@ enum EditingField {
|
|||||||
BoatsList,
|
BoatsList,
|
||||||
BoatsCanTouch,
|
BoatsCanTouch,
|
||||||
PlayerContinueOnHit,
|
PlayerContinueOnHit,
|
||||||
|
BotType,
|
||||||
Cancel,
|
Cancel,
|
||||||
OK,
|
OK,
|
||||||
}
|
}
|
||||||
@ -70,6 +72,14 @@ impl GameRulesConfigurationScreen {
|
|||||||
|
|
||||||
// Submit results
|
// Submit results
|
||||||
KeyCode::Enter => {
|
KeyCode::Enter => {
|
||||||
|
if self.curr_field == EditingField::BotType {
|
||||||
|
if let ScreenResult::Ok(t) =
|
||||||
|
SelectBotTypeScreen::default().show(terminal)?
|
||||||
|
{
|
||||||
|
self.rules.bot_type = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.curr_field == EditingField::Cancel {
|
if self.curr_field == EditingField::Cancel {
|
||||||
return Ok(ScreenResult::Canceled);
|
return Ok(ScreenResult::Canceled);
|
||||||
}
|
}
|
||||||
@ -143,7 +153,7 @@ impl GameRulesConfigurationScreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ui<B: Backend>(&mut self, f: &mut Frame<B>) {
|
fn ui<B: Backend>(&mut self, f: &mut Frame<B>) {
|
||||||
let area = centered_rect_size(50, 16, &f.size());
|
let area = centered_rect_size(50, 20, &f.size());
|
||||||
|
|
||||||
let block = Block::default().title("Game rules").borders(Borders::ALL);
|
let block = Block::default().title("Game rules").borders(Borders::ALL);
|
||||||
f.render_widget(block, area);
|
f.render_widget(block, area);
|
||||||
@ -156,7 +166,8 @@ impl GameRulesConfigurationScreen {
|
|||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
Constraint::Length(1),
|
Constraint::Length(3), // Bot type
|
||||||
|
Constraint::Length(1), // Margin
|
||||||
Constraint::Length(1), // Buttons
|
Constraint::Length(1), // Buttons
|
||||||
Constraint::Length(1), // Error message (if any)
|
Constraint::Length(1), // Error message (if any)
|
||||||
])
|
])
|
||||||
@ -206,6 +217,22 @@ impl GameRulesConfigurationScreen {
|
|||||||
);
|
);
|
||||||
f.render_widget(editor, chunks[EditingField::PlayerContinueOnHit as usize]);
|
f.render_widget(editor, chunks[EditingField::PlayerContinueOnHit as usize]);
|
||||||
|
|
||||||
|
// Select bot type
|
||||||
|
let bot_type_text = format!("Bot type: {}", self.rules.bot_type.description().name);
|
||||||
|
let text = Paragraph::new(bot_type_text.as_str()).style(
|
||||||
|
match self.curr_field == EditingField::BotType {
|
||||||
|
false => Style::default(),
|
||||||
|
true => Style::default().fg(HIGHLIGHT_COLOR),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
f.render_widget(
|
||||||
|
text,
|
||||||
|
chunks[EditingField::BotType as usize].inner(&Margin {
|
||||||
|
horizontal: 0,
|
||||||
|
vertical: 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
let buttons_chunk = Layout::default()
|
let buttons_chunk = Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
|
@ -27,7 +27,7 @@ impl Default for SelectBotTypeScreen {
|
|||||||
Self {
|
Self {
|
||||||
state: Default::default(),
|
state: Default::default(),
|
||||||
curr_selection: types.len() - 1,
|
curr_selection: types.len() - 1,
|
||||||
types,
|
types: types.to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ impl GameRules {
|
|||||||
.join(","),
|
.join(","),
|
||||||
boats_can_touch: MULTI_PLAYER_BOATS_CAN_TOUCH,
|
boats_can_touch: MULTI_PLAYER_BOATS_CAN_TOUCH,
|
||||||
player_continue_on_hit: MULTI_PLAYER_PLAYER_CAN_CONTINUE_AFTER_HIT,
|
player_continue_on_hit: MULTI_PLAYER_PLAYER_CAN_CONTINUE_AFTER_HIT,
|
||||||
bot_type: BotType::Random,
|
bot_type: BotType::Smart,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,42 @@ pub enum BotType {
|
|||||||
Smart,
|
Smart,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
impl BotType {
|
||||||
|
pub fn description(&self) -> &'static BotDescription {
|
||||||
|
BOTS_TYPES.iter().find(|d| d.r#type == *self).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, Clone)]
|
||||||
pub struct BotDescription {
|
pub struct BotDescription {
|
||||||
pub r#type: BotType,
|
pub r#type: BotType,
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub description: &'static str,
|
pub description: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BOTS_TYPES: [BotDescription; 4] = [
|
||||||
|
BotDescription {
|
||||||
|
r#type: BotType::Linear,
|
||||||
|
name: "Linear",
|
||||||
|
description: "Linear strike. Shoot A1, A2, A3, ..., B1, B2, ...",
|
||||||
|
},
|
||||||
|
BotDescription {
|
||||||
|
r#type: BotType::Random,
|
||||||
|
name: "Random",
|
||||||
|
description: "Random search. Random strike.",
|
||||||
|
},
|
||||||
|
BotDescription {
|
||||||
|
r#type: BotType::Intermediate,
|
||||||
|
name: "Intermediate",
|
||||||
|
description: "Random search. Intelligent strike.",
|
||||||
|
},
|
||||||
|
BotDescription {
|
||||||
|
r#type: BotType::Smart,
|
||||||
|
name: "Smart",
|
||||||
|
description: "Smart search. Smart strike.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct PlayConfiguration {
|
pub struct PlayConfiguration {
|
||||||
pub min_boat_len: usize,
|
pub min_boat_len: usize,
|
||||||
@ -26,7 +55,7 @@ pub struct PlayConfiguration {
|
|||||||
pub max_map_height: usize,
|
pub max_map_height: usize,
|
||||||
pub min_boats_number: usize,
|
pub min_boats_number: usize,
|
||||||
pub max_boats_number: usize,
|
pub max_boats_number: usize,
|
||||||
pub bot_types: Vec<BotDescription>,
|
pub bot_types: &'static [BotDescription],
|
||||||
pub ordinate_alphabet: &'static str,
|
pub ordinate_alphabet: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,28 +70,7 @@ impl Default for PlayConfiguration {
|
|||||||
max_map_height: MAX_MAP_HEIGHT,
|
max_map_height: MAX_MAP_HEIGHT,
|
||||||
min_boats_number: MIN_BOATS_NUMBER,
|
min_boats_number: MIN_BOATS_NUMBER,
|
||||||
max_boats_number: MAX_BOATS_NUMBER,
|
max_boats_number: MAX_BOATS_NUMBER,
|
||||||
bot_types: vec![
|
bot_types: &BOTS_TYPES,
|
||||||
BotDescription {
|
|
||||||
r#type: BotType::Linear,
|
|
||||||
name: "Linear",
|
|
||||||
description: "Linear strike. Shoot A1, A2, A3, ..., B1, B2, ...",
|
|
||||||
},
|
|
||||||
BotDescription {
|
|
||||||
r#type: BotType::Random,
|
|
||||||
name: "Ranom",
|
|
||||||
description: "Random search. Random strike.",
|
|
||||||
},
|
|
||||||
BotDescription {
|
|
||||||
r#type: BotType::Intermediate,
|
|
||||||
name: "Intermediate",
|
|
||||||
description: "Random search. Intelligent strike.",
|
|
||||||
},
|
|
||||||
BotDescription {
|
|
||||||
r#type: BotType::Smart,
|
|
||||||
name: "Smart",
|
|
||||||
description: "Smart search. Smart strike.",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ordinate_alphabet: ALPHABET,
|
ordinate_alphabet: ALPHABET,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user