refact: client : extract game_runner

This commit is contained in:
Henri Bourcereau 2024-10-16 17:37:38 +02:00
parent c5321e6186
commit acab0b0593
6 changed files with 86 additions and 125 deletions

View file

@ -1,79 +1,13 @@
use itertools::Itertools;
use bot::Bot;
use pretty_assertions::assert_eq;
use store::{
CheckerMove, DiceRoller, GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage,
};
use crate::game_runner::Game;
use store::{CheckerMove, GameEvent, GameState, PointsRules, Stage, TurnStage};
#[derive(Debug, Default)]
pub struct AppArgs {
pub seed: Option<u32>,
}
// Application Game
#[derive(Debug, Default)]
pub struct Game {
pub state: GameState,
pub dice_roller: DiceRoller,
first_move: Option<CheckerMove>,
player_id: Option<PlayerId>,
bot: Bot,
}
impl Game {
// Constructs a new instance of [`App`].
pub fn new(schools_enabled: bool, seed: Option<u64>) -> Self {
let mut state = GameState::new(schools_enabled);
// local : player
let player_id: Option<PlayerId> = state.init_player("myself");
// bot
let bot_id: PlayerId = state.init_player("bot").unwrap();
let bot_color = state.player_color_by_id(&bot_id).unwrap();
let bot: Bot = Bot::new(bot_color, schools_enabled);
let mut game = Self {
state,
dice_roller: DiceRoller::new(seed),
first_move: None,
player_id,
bot,
};
game.handle_event(&GameEvent::BeginGame {
goes_first: player_id.unwrap(),
});
game
}
pub fn handle_event(&mut self, event: &GameEvent) -> Option<GameEvent> {
if !self.state.validate(event) {
return None;
}
// println!("consuming {:?}", event);
self.state.consume(event);
// chain all successive bot actions
let bot_event = self
.bot
.handle_event(event)
.and_then(|evt| self.handle_event(&evt));
// roll dice for bot if needed
if self.bot_needs_dice_roll() {
let dice = self.dice_roller.roll();
self.handle_event(&GameEvent::RollResult {
player_id: self.bot.player_id,
dice,
})
} else {
bot_event
}
}
fn bot_needs_dice_roll(&self) -> bool {
self.state.active_player_id == self.bot.player_id
&& self.state.turn_stage == TurnStage::RollWaiting
}
}
// Application.
#[derive(Debug, Default)]
pub struct App {
@ -256,6 +190,7 @@ impl App {
}
}
use pretty_assertions::assert_eq;
#[cfg(test)]
mod tests {
use super::*;

View file

@ -0,0 +1,65 @@
use bot::Bot;
use store::{CheckerMove, DiceRoller, GameEvent, GameState, PlayerId, TurnStage};
// Application Game
#[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,
}
impl Game {
// Constructs a new instance of [`App`].
pub fn new(schools_enabled: bool, seed: Option<u64>) -> Self {
let mut state = GameState::new(schools_enabled);
// local : player
let player_id: Option<PlayerId> = state.init_player("myself");
// bot
let bot_id: PlayerId = state.init_player("bot").unwrap();
let bot_color = state.player_color_by_id(&bot_id).unwrap();
let bot: Bot = Bot::new(bot_color, schools_enabled);
let mut game = Self {
state,
dice_roller: DiceRoller::new(seed),
first_move: None,
player_id,
bot,
};
game.handle_event(&GameEvent::BeginGame {
goes_first: player_id.unwrap(),
});
game
}
pub fn handle_event(&mut self, event: &GameEvent) -> Option<GameEvent> {
if !self.state.validate(event) {
return None;
}
// println!("consuming {:?}", event);
self.state.consume(event);
// chain all successive bot actions
let bot_event = self
.bot
.handle_event(event)
.and_then(|evt| self.handle_event(&evt));
// roll dice for bot if needed
if self.bot_needs_dice_roll() {
let dice = self.dice_roller.roll();
self.handle_event(&GameEvent::RollResult {
player_id: self.bot.player_id,
dice,
})
} else {
bot_event
}
}
fn bot_needs_dice_roll(&self) -> bool {
self.state.active_player_id == self.bot.player_id
&& self.state.turn_stage == TurnStage::RollWaiting
}
}

View file

@ -1,5 +1,6 @@
// Application.
pub mod app;
mod game_runner;
use anyhow::Result;
use app::{App, AppArgs};