refact: BotStrategy dyn trait

This commit is contained in:
Henri Bourcereau 2024-11-04 17:37:36 +01:00
parent 4ee2b02a41
commit 5762187b04
6 changed files with 43 additions and 69 deletions

View file

@ -1,10 +1,8 @@
mod bot;
use store::{
CheckerMove, Color, Dice, GameEvent, GameState, Player, PlayerId, PointsRules, Stage, TurnStage,
};
use store::{CheckerMove, Color, GameEvent, GameState, PlayerId, PointsRules, TurnStage};
pub trait BotStrategy {
pub trait BotStrategy: std::fmt::Debug {
fn get_game(&self) -> &GameState;
fn get_mut_game(&mut self) -> &mut GameState;
fn calculate_points(&self) -> u8;
@ -27,18 +25,11 @@ pub struct DefaultStrategy {
impl Default for DefaultStrategy {
fn default() -> Self {
let game = GameState::default();
let mut strategy = Self {
Self {
game,
player_id: 2,
color: Color::Black,
};
strategy
}
}
impl DefaultStrategy {
fn new() -> Self {
Self::default()
}
}
}
@ -95,35 +86,34 @@ impl BotStrategy for DefaultStrategy {
}
#[derive(Debug)]
pub struct Bot<BotStrategy> {
pub struct Bot {
pub player_id: PlayerId,
strategy: BotStrategy,
color: Color,
schools_enabled: bool,
strategy: Box<dyn BotStrategy>,
// color: Color,
// schools_enabled: bool,
}
impl Default for Bot<DefaultStrategy> {
impl Default for Bot {
fn default() -> Self {
let strategy = DefaultStrategy::default();
Self {
player_id: 2,
strategy: DefaultStrategy::default(),
color: Color::Black,
schools_enabled: false,
strategy: Box::new(strategy),
// color: Color::Black,
// schools_enabled: false,
}
}
}
impl<BS> Bot<BS>
where
BS: BotStrategy,
{
impl Bot {
/// new initialize a bot
/// # Examples
/// ```let mut bot = Bot::new(Color::Black);
/// assert_eq!(bot.game.stage, Stage::PreGame);
/// ```
pub fn new(mut strategy: BS, color: Color, schools_enabled: bool) -> Self {
let game = strategy.get_mut_game();
// pub fn new(mut strategy: Box<dyn BotStrategy>, color: Color, schools_enabled: bool) -> Self {
pub fn new(mut strategy: Box<dyn BotStrategy>, color: Color) -> Self {
// let game = strategy.get_mut_game();
strategy.init_players();
let player_id = match color {
Color::White => 1,
@ -133,8 +123,8 @@ where
Self {
player_id,
strategy,
color,
schools_enabled: false,
// color,
// schools_enabled: false,
}
}
@ -174,16 +164,19 @@ where
#[cfg(test)]
mod tests {
use super::*;
use store::{Dice, Stage};
#[test]
fn test_new() {
let bot = Bot::new(DefaultStrategy::new(), Color::Black, false);
let bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black);
// let bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black, false);
assert_eq!(bot.get_state().stage, Stage::PreGame);
}
#[test]
fn test_consume() {
let mut bot = Bot::new(DefaultStrategy::new(), Color::Black, false);
let mut bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black);
// let mut bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black, false);
let mut event = bot.handle_event(&GameEvent::BeginGame { goes_first: 2 });
assert_eq!(event, Some(GameEvent::Roll { player_id: 2 }));
assert_eq!(bot.get_state().active_player_id, 2);

View file

@ -1,8 +1,7 @@
use itertools::Itertools;
use crate::game_runner::Game;
use bot::BotStrategy;
use store::{CheckerMove, GameEvent, GameState, PointsRules, Stage, TurnStage};
use store::{CheckerMove, GameEvent, GameState, Stage, TurnStage};
#[derive(Debug, Default)]
pub struct AppArgs {
@ -73,15 +72,15 @@ impl App {
let dice = self.game.dice_roller.roll();
// get correct points for these board and dice
let points_rules = PointsRules::new(
&self
.game
.state
.player_color_by_id(&self.game.player_id.unwrap())
.unwrap(),
&self.game.state.board,
dice,
);
// let points_rules = PointsRules::new(
// &self
// .game
// .state
// .player_color_by_id(&self.game.player_id.unwrap())
// .unwrap(),
// &self.game.state.board,
// dice,
// );
self.game.handle_event(&GameEvent::RollResult {
player_id: self.game.player_id.unwrap(),
dice,
@ -191,10 +190,10 @@ impl App {
}
}
use pretty_assertions::assert_eq;
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_display() {

View file

@ -1,26 +1,14 @@
use bot::{Bot, BotStrategy, DefaultStrategy};
use bot::{Bot, DefaultStrategy};
use store::{CheckerMove, DiceRoller, GameEvent, GameState, PlayerId, TurnStage};
// Application Game
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Game {
pub state: GameState,
pub dice_roller: DiceRoller,
pub first_move: Option<CheckerMove>,
pub player_id: Option<PlayerId>,
bot: Bot<DefaultStrategy>,
}
impl Default for Game {
fn default() -> Self {
Self {
state: GameState::default(),
dice_roller: DiceRoller::default(),
first_move: None,
player_id: None,
bot: Bot::default(),
}
}
bot: Bot,
}
impl Game {
@ -32,8 +20,9 @@ impl Game {
// bot
let bot_id: PlayerId = state.init_player("bot").unwrap();
let bot_color = state.player_color_by_id(&bot_id).unwrap();
let bot_strategy = DefaultStrategy::default();
let bot: Bot<DefaultStrategy> = Bot::new(bot_strategy, bot_color, schools_enabled);
let bot_strategy = Box::new(DefaultStrategy::default());
// let bot: Bot = Bot::new(bot_strategy, bot_color, schools_enabled);
let bot: Bot = Bot::new(bot_strategy, bot_color);
let mut game = Self {
state,

View file

@ -25,6 +25,6 @@ pub fn render(app: &mut App, f: &mut Frame) {
)
.style(Style::default().fg(Color::Yellow))
.alignment(Alignment::Center),
f.size(),
f.area(),
)
}

View file

@ -310,7 +310,7 @@ impl Board {
/// Check if a field is blocked for a player
pub fn blocked(&self, color: &Color, field: Field) -> Result<bool, Error> {
// the square is blocked on the opponent rest corner
let opp_corner_field = if color == &Color::White { 13 } else { 12 };
// let opp_corner_field = if color == &Color::White { 13 } else { 12 };
self.passage_blocked(color, field)
// .map(|blocked| blocked || opp_corner_field == field)
}

View file

@ -1,4 +1,3 @@
use crate::Error;
use rand::distributions::{Distribution, Uniform};
use rand::{rngs::StdRng, SeedableRng};
use serde::{Deserialize, Serialize};
@ -76,12 +75,6 @@ impl Dice {
// }
}
/// Trait to roll the dices
pub trait Roll {
/// Roll the dices
fn roll(&mut self) -> &mut Self;
}
#[cfg(test)]
mod tests {
use super::*;