bots : wip 2 bots handling

This commit is contained in:
Henri Bourcereau 2025-01-03 17:40:08 +01:00
parent 71992ccf7c
commit 2fe2f66c13
2 changed files with 52 additions and 17 deletions

View file

@ -23,7 +23,7 @@ impl GameRunner {
let player_id: Option<PlayerId> = state.init_player("myself"); let player_id: Option<PlayerId> = state.init_player("myself");
// bots // bots
let bots = bot_strategies let bots: Vec<Bot> = bot_strategies
.into_iter() .into_iter()
.map(|strategy| { .map(|strategy| {
let bot_id: PlayerId = state.init_player("bot").unwrap(); let bot_id: PlayerId = state.init_player("bot").unwrap();
@ -35,6 +35,11 @@ impl GameRunner {
// let bot: Bot = Bot::new(bot_strategy, bot_color, schools_enabled); // let bot: Bot = Bot::new(bot_strategy, bot_color, schools_enabled);
// let bot: Bot = Bot::new(bot_strategy, bot_color); // let bot: Bot = Bot::new(bot_strategy, bot_color);
let first_player_id = if bots.len() > 1 {
bots[0].player_id
} else {
player_id.unwrap()
};
let mut game = Self { let mut game = Self {
state, state,
dice_roller: DiceRoller::new(seed), dice_roller: DiceRoller::new(seed),
@ -43,7 +48,7 @@ impl GameRunner {
bots, bots,
}; };
game.handle_event(&GameEvent::BeginGame { game.handle_event(&GameEvent::BeginGame {
goes_first: player_id.unwrap(), goes_first: first_player_id,
}); });
game game
} }
@ -54,24 +59,39 @@ impl GameRunner {
} }
// println!("consuming {:?}", event); // println!("consuming {:?}", event);
self.state.consume(event); self.state.consume(event);
// chain all successive bot actions // chain all successive bot actions
let bot_event = self.bots[0] if self.bots.is_empty() {
.handle_event(event) return None;
.and_then(|evt| self.handle_event(&evt)); }
// roll dice for bot if needed
if self.bot_needs_dice_roll() { // Collect bot actions to avoid borrow conflicts
let bot_events: Vec<GameEvent> = self
.bots
.iter_mut()
.filter(|bot| Some(bot.player_id) != event.player_id())
.filter_map(|bot| bot.handle_event(event))
.collect();
let mut next_event = None;
for bot_event in bot_events {
let bot_result_event = self.handle_event(&bot_event);
if let Some(bot_id) = bot_event.player_id() {
next_event = if self.bot_needs_dice_roll(bot_id) {
let dice = self.dice_roller.roll(); let dice = self.dice_roller.roll();
self.handle_event(&GameEvent::RollResult { self.handle_event(&GameEvent::RollResult {
player_id: self.bots[0].player_id, player_id: bot_id,
dice, dice,
}) })
} else { } else {
bot_event bot_result_event
} }
} }
}
next_event
}
fn bot_needs_dice_roll(&self) -> bool { fn bot_needs_dice_roll(&self, bot_id: PlayerId) -> bool {
self.state.active_player_id == self.bots[0].player_id self.state.active_player_id == bot_id && self.state.turn_stage == TurnStage::RollWaiting
&& self.state.turn_stage == TurnStage::RollWaiting
} }
} }

View file

@ -612,6 +612,21 @@ pub enum GameEvent {
}, },
} }
impl GameEvent {
pub fn player_id(&self) -> Option<PlayerId> {
match self {
Self::PlayerJoined { player_id, name } => Some(*player_id),
Self::PlayerDisconnected { player_id } => Some(*player_id),
Self::Roll { player_id } => Some(*player_id),
Self::RollResult { player_id, dice } => Some(*player_id),
Self::Mark { player_id, points } => Some(*player_id),
Self::Go { player_id } => Some(*player_id),
Self::Move { player_id, moves } => Some(*player_id),
_ => None,
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;