105 lines
2.9 KiB
Rust
Raw Normal View History

2022-09-10 15:02:45 +02:00
use crate::consts::*;
2022-09-12 16:38:14 +02:00
use crate::data::{BotType, PlayConfiguration};
2022-09-10 15:02:45 +02:00
2022-09-15 18:04:22 +02:00
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]
2022-09-10 15:02:45 +02:00
pub struct GameRules {
pub map_width: usize,
pub map_height: usize,
2022-09-11 16:48:20 +02:00
pub boats_str: String,
2022-09-10 15:02:45 +02:00
pub boats_can_touch: bool,
pub player_continue_on_hit: bool,
2022-09-11 16:48:20 +02:00
pub bot_type: BotType,
2022-09-10 15:02:45 +02:00
}
impl GameRules {
2022-09-11 16:51:14 +02:00
pub fn random_players_rules() -> Self {
2022-09-10 15:02:45 +02:00
Self {
map_width: MULTI_PLAYER_MAP_WIDTH,
map_height: MULTI_PLAYER_MAP_HEIGHT,
2022-09-11 16:48:20 +02:00
boats_str: MULTI_PLAYER_PLAYER_BOATS
.iter()
.map(usize::to_string)
.collect::<Vec<_>>()
.join(","),
2022-09-10 15:02:45 +02:00
boats_can_touch: MULTI_PLAYER_BOATS_CAN_TOUCH,
player_continue_on_hit: MULTI_PLAYER_PLAYER_CAN_CONTINUE_AFTER_HIT,
2022-09-11 16:48:20 +02:00
bot_type: BotType::Random,
2022-09-10 15:02:45 +02:00
}
}
2022-09-17 12:02:13 +02:00
pub fn with_bot_type(mut self, t: BotType) -> Self {
self.bot_type = t;
self
}
2022-09-13 17:25:14 +02:00
/// Set the list of boats for this configuration
pub fn set_boats_list(&mut self, boats: &[usize]) {
2022-09-13 17:26:40 +02:00
self.boats_str = boats
.iter()
.map(usize::to_string)
.collect::<Vec<_>>()
.join(",");
2022-09-13 17:25:14 +02:00
}
2022-09-11 16:51:14 +02:00
/// Get the list of boats for this configuration
pub fn boats_list(&self) -> Vec<usize> {
2022-09-11 16:48:20 +02:00
self.boats_str
.split(',')
.map(|s| s.parse::<usize>().unwrap_or_default())
.collect()
}
2022-09-15 19:56:11 +02:00
/// Remove last boat
pub fn pop_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
2022-09-10 15:02:45 +02:00
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!");
}
2022-09-11 16:51:14 +02:00
if self.boats_list().len() < config.min_boats_number
|| self.boats_list().len() > config.max_boats_number
2022-09-11 16:48:20 +02:00
{
2022-09-10 15:02:45 +02:00
errors.push("Number of boats is invalid!");
}
2022-09-11 16:51:14 +02:00
for boat in self.boats_list() {
2022-09-11 16:48:20 +02:00
if boat < config.min_boat_len || boat > config.max_boat_len {
errors.push("A boat has an invalid length");
}
}
2022-09-10 15:02:45 +02:00
errors
}
}
#[cfg(test)]
mod test {
use crate::data::GameRules;
#[test]
fn multi_players_config() {
2022-09-11 16:51:14 +02:00
assert!(GameRules::random_players_rules().get_errors().is_empty());
2022-09-10 15:02:45 +02:00
}
2022-09-11 16:48:20 +02:00
}