Start to build cli player
This commit is contained in:
122
rust/sea_battle_backend/src/data/game_rules.rs
Normal file
122
rust/sea_battle_backend/src/data/game_rules.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use crate::consts::*;
|
||||
use crate::data::{BotType, PlayConfiguration};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
|
||||
#[serde_as]
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct GameRules {
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub map_width: usize,
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub map_height: usize,
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub boats_str: String,
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub boats_can_touch: bool,
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub player_continue_on_hit: bool,
|
||||
pub bot_type: BotType,
|
||||
}
|
||||
|
||||
impl Default for GameRules {
|
||||
fn default() -> Self {
|
||||
Self::random_players_rules()
|
||||
}
|
||||
}
|
||||
|
||||
impl GameRules {
|
||||
pub fn random_players_rules() -> Self {
|
||||
Self {
|
||||
map_width: MULTI_PLAYER_MAP_WIDTH,
|
||||
map_height: MULTI_PLAYER_MAP_HEIGHT,
|
||||
boats_str: MULTI_PLAYER_PLAYER_BOATS
|
||||
.iter()
|
||||
.map(usize::to_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
boats_can_touch: MULTI_PLAYER_BOATS_CAN_TOUCH,
|
||||
player_continue_on_hit: MULTI_PLAYER_PLAYER_CAN_CONTINUE_AFTER_HIT,
|
||||
bot_type: BotType::Random,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_bot_type(mut self, t: BotType) -> Self {
|
||||
self.bot_type = t;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_player_continue_on_hit(mut self, c: bool) -> Self {
|
||||
self.player_continue_on_hit = c;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the list of boats for this configuration
|
||||
pub fn set_boats_list(&mut self, boats: &[usize]) {
|
||||
self.boats_str = boats
|
||||
.iter()
|
||||
.map(usize::to_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
}
|
||||
|
||||
/// Get the list of boats for this configuration
|
||||
pub fn boats_list(&self) -> Vec<usize> {
|
||||
self.boats_str
|
||||
.split(',')
|
||||
.map(|s| s.parse::<usize>().unwrap_or_default())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Remove last boat
|
||||
pub fn remove_last_boat(&mut self) -> usize {
|
||||
let list = self.boats_list();
|
||||
self.set_boats_list(&list[0..list.len() - 1]);
|
||||
*list.last().unwrap()
|
||||
}
|
||||
|
||||
/// Add a boat to the list of boats
|
||||
pub fn add_boat(&mut self, len: usize) {
|
||||
let mut list = self.boats_list();
|
||||
list.push(len);
|
||||
self.set_boats_list(&list[0..list.len() - 1]);
|
||||
}
|
||||
|
||||
/// Check game rules errors
|
||||
pub fn get_errors(&self) -> Vec<&str> {
|
||||
let config = PlayConfiguration::default();
|
||||
|
||||
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_height < config.min_map_height || self.map_height > config.max_map_height {
|
||||
errors.push("Map height is outside bounds!");
|
||||
}
|
||||
|
||||
if self.boats_list().len() < config.min_boats_number
|
||||
|| self.boats_list().len() > config.max_boats_number
|
||||
{
|
||||
errors.push("Number of boats is invalid!");
|
||||
}
|
||||
|
||||
for boat in self.boats_list() {
|
||||
if boat < config.min_boat_len || boat > config.max_boat_len {
|
||||
errors.push("A boat has an invalid length");
|
||||
}
|
||||
}
|
||||
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::data::GameRules;
|
||||
|
||||
#[test]
|
||||
fn multi_players_config() {
|
||||
assert!(GameRules::random_players_rules().get_errors().is_empty());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user