diff --git a/bot/src/lib.rs b/bot/src/lib.rs index 5a02197..9a54510 100644 --- a/bot/src/lib.rs +++ b/bot/src/lib.rs @@ -4,76 +4,31 @@ use store::{ CheckerMove, Color, Dice, GameEvent, GameState, Player, PlayerId, PointsRules, Stage, TurnStage, }; -#[derive(Debug)] -pub struct Bot { - pub game: GameState, +trait BotStragegy<'gs> { + // fn get_game(&self) -> &GameState; + fn calculate_points(&self) -> u8; + fn calculate_adv_points(&self) -> u8; + fn choose_move(&self) -> (CheckerMove, CheckerMove); + fn set_game(&mut self, game: &'gs GameState); + fn set_player_id(&mut self, player_id: PlayerId); +} + +struct DefaultStrategy<'gs> { + pub game: &'gs GameState, pub player_id: PlayerId, - color: Color, - schools_enabled: bool, + pub color: Color, } -impl Default for Bot { - fn default() -> Bot { - Bot { - game: GameState::default(), - player_id: 1, - color: Color::Black, - schools_enabled: false, - } +impl<'gs> BotStragegy<'gs> for DefaultStrategy<'gs> { + // fn get_game(&self) -> &GameState { + // &self.game + // } + + fn set_game(&mut self, game: &'gs GameState) { + self.game = game; } -} - -// impl PlayerEngine for Bot {} - -impl Bot { - /// new initialize a bot - /// # Examples - /// ```let mut bot = Bot::new(Color::Black); - /// assert_eq!(bot.game.stage, Stage::PreGame); - /// ``` - pub fn new(color: Color, schools_enabled: bool) -> Self { - let mut game = GameState::default(); - game.init_player("p1"); - game.init_player("p2"); - - let player_id = match color { - Color::White => 1, - Color::Black => 2, - }; - - Self { - game, - player_id, - color, - schools_enabled: false, - } - } - - pub fn handle_event(&mut self, event: &GameEvent) -> Option { - self.game.consume(event); - // println!("bot game {:?}", self.game); - // println!("bot player_id {:?}", self.player_id); - if self.game.active_player_id == self.player_id { - return match self.game.turn_stage { - TurnStage::MarkAdvPoints => Some(GameEvent::Mark { - player_id: self.player_id, - points: self.calculate_adv_points(), - }), - TurnStage::RollDice => Some(GameEvent::Roll { - player_id: self.player_id, - }), - TurnStage::MarkPoints => Some(GameEvent::Mark { - player_id: self.player_id, - points: self.calculate_points(), - }), - TurnStage::Move => Some(GameEvent::Move { - player_id: self.player_id, - moves: self.choose_move(), - }), - _ => None, - }; - } - None + fn set_player_id(&mut self, player_id: PlayerId) { + self.player_id = player_id; } fn calculate_points(&self) -> u8 { @@ -116,6 +71,76 @@ impl Bot { } } +#[derive(Debug)] +pub struct Bot { + pub game: GameState, + pub player_id: PlayerId, + strategy: BotStragegy, + color: Color, + schools_enabled: bool, +} + +// impl PlayerEngine for Bot {} + +impl Bot +where + BS: BotStragegy<'gs>, +{ + /// 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 mut game = GameState::default(); + game.init_player("p1"); + game.init_player("p2"); + + let player_id = match color { + Color::White => 1, + Color::Black => 2, + }; + + strategy.set_game(&game); + strategy.set_player_id(player_id); + + Self { + game, + player_id, + strategy, + color, + schools_enabled: false, + } + } + + pub fn handle_event(&mut self, event: &GameEvent) -> Option { + self.game.consume(event); + // println!("bot game {:?}", self.game); + // println!("bot player_id {:?}", self.player_id); + if self.game.active_player_id == self.player_id { + return match self.game.turn_stage { + TurnStage::MarkAdvPoints => Some(GameEvent::Mark { + player_id: self.player_id, + points: self.strategy.calculate_adv_points(), + }), + TurnStage::RollDice => Some(GameEvent::Roll { + player_id: self.player_id, + }), + TurnStage::MarkPoints => Some(GameEvent::Mark { + player_id: self.player_id, + points: self.strategy.calculate_points(), + }), + TurnStage::Move => Some(GameEvent::Move { + player_id: self.player_id, + moves: self.strategy.choose_move(), + }), + _ => None, + }; + } + None + } +} + #[cfg(test)] mod tests { use super::*;