From acab0b0593e9b05d9b4db86f9f1b126f6137a94f Mon Sep 17 00:00:00 2001 From: Henri Bourcereau Date: Wed, 16 Oct 2024 17:37:38 +0200 Subject: [PATCH] refact: client : extract game_runner --- .pre-commit-config.yaml | 2 +- client_cli/src/app.rs | 71 ++--------------------------------- client_cli/src/game_runner.rs | 65 ++++++++++++++++++++++++++++++++ client_cli/src/main.rs | 1 + devenv.lock | 66 +++++++------------------------- doc/traité.md | 6 +-- 6 files changed, 86 insertions(+), 125 deletions(-) create mode 100644 client_cli/src/game_runner.rs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3cecf95..fa06e16 120000 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1 +1 @@ -/nix/store/qp1vc91wm7s7vz337hpv6zimpc4gcvf0-pre-commit-config.json \ No newline at end of file +/nix/store/i4sgk0h4rjc84waf065w8xkrwvxlnhpw-pre-commit-config.json \ No newline at end of file diff --git a/client_cli/src/app.rs b/client_cli/src/app.rs index c640565..186375f 100644 --- a/client_cli/src/app.rs +++ b/client_cli/src/app.rs @@ -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, } -// Application Game -#[derive(Debug, Default)] -pub struct Game { - pub state: GameState, - pub dice_roller: DiceRoller, - first_move: Option, - player_id: Option, - bot: Bot, -} - -impl Game { - // Constructs a new instance of [`App`]. - pub fn new(schools_enabled: bool, seed: Option) -> Self { - let mut state = GameState::new(schools_enabled); - // local : player - let player_id: Option = 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 { - 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::*; diff --git a/client_cli/src/game_runner.rs b/client_cli/src/game_runner.rs new file mode 100644 index 0000000..1a6a290 --- /dev/null +++ b/client_cli/src/game_runner.rs @@ -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, + pub player_id: Option, + bot: Bot, +} + +impl Game { + // Constructs a new instance of [`App`]. + pub fn new(schools_enabled: bool, seed: Option) -> Self { + let mut state = GameState::new(schools_enabled); + // local : player + let player_id: Option = 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 { + 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 + } +} diff --git a/client_cli/src/main.rs b/client_cli/src/main.rs index 007d2d4..5f0cde4 100644 --- a/client_cli/src/main.rs +++ b/client_cli/src/main.rs @@ -1,5 +1,6 @@ // Application. pub mod app; +mod game_runner; use anyhow::Result; use app::{App, AppArgs}; diff --git a/devenv.lock b/devenv.lock index ea67978..a86bf8f 100644 --- a/devenv.lock +++ b/devenv.lock @@ -3,11 +3,10 @@ "devenv": { "locked": { "dir": "src/modules", - "lastModified": 1698243190, - "narHash": "sha256-n+SbyNQRhUcaZoU00d+7wi17HJpw/kAUrXOL4zRcqE8=", + "lastModified": 1729076865, "owner": "cachix", "repo": "devenv", - "rev": "86f476f7edb86159fd20764489ab4e4df6edb4b6", + "rev": "9803535e5d124b502165e51d9caacf38b9dbe463", "type": "github" }, "original": { @@ -20,11 +19,10 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -33,24 +31,6 @@ "type": "github" } }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -59,11 +39,10 @@ ] }, "locked": { - "lastModified": 1660459072, - "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "lastModified": 1709087332, "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", "type": "github" }, "original": { @@ -74,11 +53,10 @@ }, "nixpkgs": { "locked": { - "lastModified": 1698553279, - "narHash": "sha256-T/9P8yBSLcqo/v+FTOBK+0rjzjPMctVymZydbvR/Fak=", + "lastModified": 1728538411, "owner": "NixOS", "repo": "nixpkgs", - "rev": "90e85bc7c1a6fc0760a94ace129d3a1c61c3d035", + "rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221", "type": "github" }, "original": { @@ -90,16 +68,15 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1685801374, - "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "lastModified": 1728909085, "owner": "NixOS", "repo": "nixpkgs", - "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "rev": "c0b1da36f7c34a7146501f684e9ebdf15d2bebf8", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.05", + "ref": "nixos-24.05", "repo": "nixpkgs", "type": "github" } @@ -107,7 +84,6 @@ "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", - "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -115,11 +91,10 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1698227354, - "narHash": "sha256-Fi5H9jbaQLmLw9qBi/mkR33CoFjNbobo5xWdX4tKz1Q=", + "lastModified": 1728778939, "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "bd38df3d508dfcdff52cd243d297f218ed2257bf", + "rev": "ff68f91754be6f3427e4986d7949e6273659be1d", "type": "github" }, "original": { @@ -134,21 +109,6 @@ "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks" } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/doc/traité.md b/doc/traité.md index 1908a80..e2241ad 100644 --- a/doc/traité.md +++ b/doc/traité.md @@ -35,6 +35,6 @@ L'encyclopédie ## rêveries -Trictrac : un domaine grand et complexe, un univers dans lequel on peut s'absorber. Un jeu geek parfait. Qui a la noblesse d'avoir été populaire, qui a la noblesse de règles nécessitant apprentissage et presse companionage. -Pourquoi s'investir dans ce genre d'activité ? Toucher un absolu. Sauver de la mort une pépite. Entrer dans le monde des morts comme Orphée ou Ulysse ? -Et maîtriser un vocabulaire, des gestes, des règles de plus en plus fine, discutées au fil des siècles. +Trictrac : un domaine grand et complexe, un univers dans lequel on peut s'absorber. Un jeu geek parfait. Qui a la noblesse d'avoir été populaire, qui a la noblesse de règles nécessitant apprentissage et presque companionage. +Pourquoi s'investir dans ce genre d'activité ? Toucher un absolu. Sauver de la mort une pépite du passé. Entrer dans le monde des morts comme Orphée ou Ulysse ? +Et maîtriser un vocabulaire, des gestes, des règles affinées au fil des siècles.