2024-11-07 16:51:33 +01:00
|
|
|
mod strategy;
|
2024-03-24 18:37:35 +01:00
|
|
|
|
2024-11-04 17:37:36 +01:00
|
|
|
use store::{CheckerMove, Color, GameEvent, GameState, PlayerId, PointsRules, TurnStage};
|
2024-11-07 16:51:33 +01:00
|
|
|
pub use strategy::default::DefaultStrategy;
|
2024-03-24 18:37:35 +01:00
|
|
|
|
2024-11-04 17:37:36 +01:00
|
|
|
pub trait BotStrategy: std::fmt::Debug {
|
2024-10-17 17:35:07 +02:00
|
|
|
fn get_game(&self) -> &GameState;
|
|
|
|
|
fn get_mut_game(&mut self) -> &mut GameState;
|
|
|
|
|
fn calculate_points(&self) -> u8;
|
|
|
|
|
fn calculate_adv_points(&self) -> u8;
|
|
|
|
|
fn choose_move(&self) -> (CheckerMove, CheckerMove);
|
2025-01-09 21:27:24 +01:00
|
|
|
fn choose_go(&self) -> bool;
|
2024-10-17 17:35:07 +02:00
|
|
|
fn set_player_id(&mut self, player_id: PlayerId);
|
2025-01-06 20:27:16 +01:00
|
|
|
fn set_color(&mut self, color: Color);
|
2024-10-17 17:35:07 +02:00
|
|
|
fn init_players(&mut self) {
|
|
|
|
|
self.get_mut_game().init_player("p1");
|
|
|
|
|
self.get_mut_game().init_player("p2");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2024-11-04 17:37:36 +01:00
|
|
|
pub struct Bot {
|
2024-10-17 17:35:07 +02:00
|
|
|
pub player_id: PlayerId,
|
2024-11-04 17:37:36 +01:00
|
|
|
strategy: Box<dyn BotStrategy>,
|
|
|
|
|
// color: Color,
|
|
|
|
|
// schools_enabled: bool,
|
2024-03-24 18:37:35 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-04 17:37:36 +01:00
|
|
|
impl Default for Bot {
|
2024-10-17 17:35:07 +02:00
|
|
|
fn default() -> Self {
|
2024-11-04 17:37:36 +01:00
|
|
|
let strategy = DefaultStrategy::default();
|
2024-10-17 17:35:07 +02:00
|
|
|
Self {
|
|
|
|
|
player_id: 2,
|
2024-11-04 17:37:36 +01:00
|
|
|
strategy: Box::new(strategy),
|
|
|
|
|
// color: Color::Black,
|
|
|
|
|
// schools_enabled: false,
|
2024-03-24 18:37:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-04 17:37:36 +01:00
|
|
|
impl Bot {
|
2024-03-24 18:37:35 +01:00
|
|
|
/// new initialize a bot
|
2024-11-04 17:37:36 +01:00
|
|
|
// 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();
|
2024-10-17 17:35:07 +02:00
|
|
|
strategy.init_players();
|
2024-03-24 18:37:35 +01:00
|
|
|
let player_id = match color {
|
|
|
|
|
Color::White => 1,
|
|
|
|
|
Color::Black => 2,
|
|
|
|
|
};
|
2024-10-17 17:35:07 +02:00
|
|
|
strategy.set_player_id(player_id);
|
2025-01-06 20:27:16 +01:00
|
|
|
strategy.set_color(color);
|
2024-03-24 18:37:35 +01:00
|
|
|
Self {
|
|
|
|
|
player_id,
|
2024-10-17 17:35:07 +02:00
|
|
|
strategy,
|
2024-11-04 17:37:36 +01:00
|
|
|
// color,
|
|
|
|
|
// schools_enabled: false,
|
2024-03-24 18:37:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 16:10:53 +01:00
|
|
|
pub fn handle_event(&mut self, event: &GameEvent) -> Option<GameEvent> {
|
2024-10-17 17:35:07 +02:00
|
|
|
let game = self.strategy.get_mut_game();
|
|
|
|
|
game.consume(event);
|
|
|
|
|
if game.active_player_id == self.player_id {
|
|
|
|
|
return match game.turn_stage {
|
2024-09-20 20:39:18 +02:00
|
|
|
TurnStage::MarkAdvPoints => Some(GameEvent::Mark {
|
|
|
|
|
player_id: self.player_id,
|
2024-10-17 17:35:07 +02:00
|
|
|
points: self.strategy.calculate_adv_points(),
|
2024-09-20 20:39:18 +02:00
|
|
|
}),
|
2024-03-24 18:37:35 +01:00
|
|
|
TurnStage::RollDice => Some(GameEvent::Roll {
|
|
|
|
|
player_id: self.player_id,
|
|
|
|
|
}),
|
|
|
|
|
TurnStage::MarkPoints => Some(GameEvent::Mark {
|
|
|
|
|
player_id: self.player_id,
|
2024-10-17 17:35:07 +02:00
|
|
|
points: self.strategy.calculate_points(),
|
2024-03-24 18:37:35 +01:00
|
|
|
}),
|
|
|
|
|
TurnStage::Move => Some(GameEvent::Move {
|
|
|
|
|
player_id: self.player_id,
|
2024-10-17 17:35:07 +02:00
|
|
|
moves: self.strategy.choose_move(),
|
2024-03-24 18:37:35 +01:00
|
|
|
}),
|
2025-01-09 21:27:24 +01:00
|
|
|
TurnStage::HoldOrGoChoice => {
|
|
|
|
|
if self.strategy.choose_go() {
|
|
|
|
|
Some(GameEvent::Go {
|
|
|
|
|
player_id: self.player_id,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
Some(GameEvent::Move {
|
|
|
|
|
player_id: self.player_id,
|
|
|
|
|
moves: self.strategy.choose_move(),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-27 21:10:15 +01:00
|
|
|
_ => None,
|
2024-03-24 18:37:35 +01:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-17 17:35:07 +02:00
|
|
|
pub fn get_state(&self) -> &GameState {
|
|
|
|
|
self.strategy.get_game()
|
2024-03-24 18:37:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
2024-11-04 17:37:36 +01:00
|
|
|
use store::{Dice, Stage};
|
2024-03-24 18:37:35 +01:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_new() {
|
2024-11-04 17:37:36 +01:00
|
|
|
let bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black);
|
|
|
|
|
// let bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black, false);
|
2024-10-17 17:35:07 +02:00
|
|
|
assert_eq!(bot.get_state().stage, Stage::PreGame);
|
2024-03-24 18:37:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_consume() {
|
2024-11-04 17:37:36 +01:00
|
|
|
let mut bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black);
|
|
|
|
|
// let mut bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black, false);
|
2024-03-30 16:10:53 +01:00
|
|
|
let mut event = bot.handle_event(&GameEvent::BeginGame { goes_first: 2 });
|
2024-03-24 18:37:35 +01:00
|
|
|
assert_eq!(event, Some(GameEvent::Roll { player_id: 2 }));
|
2024-10-17 17:35:07 +02:00
|
|
|
assert_eq!(bot.get_state().active_player_id, 2);
|
2024-03-24 18:37:35 +01:00
|
|
|
|
2024-03-30 16:10:53 +01:00
|
|
|
event = bot.handle_event(&GameEvent::BeginGame { goes_first: 1 });
|
2024-03-24 18:37:35 +01:00
|
|
|
assert_eq!(event, None);
|
|
|
|
|
|
2024-10-17 17:35:07 +02:00
|
|
|
assert_eq!(bot.get_state().active_player_id, 1);
|
2024-03-30 16:10:53 +01:00
|
|
|
bot.handle_event(&GameEvent::RollResult {
|
2024-10-17 17:35:07 +02:00
|
|
|
player_id: 1,
|
2024-03-24 18:37:35 +01:00
|
|
|
dice: Dice { values: (2, 3) },
|
|
|
|
|
});
|
2024-10-17 17:35:07 +02:00
|
|
|
assert_eq!(bot.get_state().turn_stage, TurnStage::Move);
|
2024-03-24 18:37:35 +01:00
|
|
|
}
|
|
|
|
|
}
|