refact: client : extract game_runner
This commit is contained in:
parent
c5321e6186
commit
acab0b0593
|
|
@ -1 +1 @@
|
||||||
/nix/store/qp1vc91wm7s7vz337hpv6zimpc4gcvf0-pre-commit-config.json
|
/nix/store/i4sgk0h4rjc84waf065w8xkrwvxlnhpw-pre-commit-config.json
|
||||||
|
|
@ -1,79 +1,13 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use bot::Bot;
|
use crate::game_runner::Game;
|
||||||
use pretty_assertions::assert_eq;
|
use store::{CheckerMove, GameEvent, GameState, PointsRules, Stage, TurnStage};
|
||||||
use store::{
|
|
||||||
CheckerMove, DiceRoller, GameEvent, GameState, PlayerId, PointsRules, Stage, TurnStage,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct AppArgs {
|
pub struct AppArgs {
|
||||||
pub seed: Option<u32>,
|
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.
|
// Application.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
|
|
@ -256,6 +190,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
65
client_cli/src/game_runner.rs
Normal file
65
client_cli/src/game_runner.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// Application.
|
// Application.
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
mod game_runner;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use app::{App, AppArgs};
|
use app::{App, AppArgs};
|
||||||
|
|
|
||||||
66
devenv.lock
66
devenv.lock
|
|
@ -3,11 +3,10 @@
|
||||||
"devenv": {
|
"devenv": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "src/modules",
|
"dir": "src/modules",
|
||||||
"lastModified": 1698243190,
|
"lastModified": 1729076865,
|
||||||
"narHash": "sha256-n+SbyNQRhUcaZoU00d+7wi17HJpw/kAUrXOL4zRcqE8=",
|
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "devenv",
|
"repo": "devenv",
|
||||||
"rev": "86f476f7edb86159fd20764489ab4e4df6edb4b6",
|
"rev": "9803535e5d124b502165e51d9caacf38b9dbe463",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -20,11 +19,10 @@
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673956053,
|
"lastModified": 1696426674,
|
||||||
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -33,24 +31,6 @@
|
||||||
"type": "github"
|
"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": {
|
"gitignore": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|
@ -59,11 +39,10 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1660459072,
|
"lastModified": 1709087332,
|
||||||
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
|
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "gitignore.nix",
|
"repo": "gitignore.nix",
|
||||||
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
|
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -74,11 +53,10 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1698553279,
|
"lastModified": 1728538411,
|
||||||
"narHash": "sha256-T/9P8yBSLcqo/v+FTOBK+0rjzjPMctVymZydbvR/Fak=",
|
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "90e85bc7c1a6fc0760a94ace129d3a1c61c3d035",
|
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -90,16 +68,15 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1685801374,
|
"lastModified": 1728909085,
|
||||||
"narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
|
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
|
"rev": "c0b1da36f7c34a7146501f684e9ebdf15d2bebf8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-23.05",
|
"ref": "nixos-24.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +84,6 @@
|
||||||
"pre-commit-hooks": {
|
"pre-commit-hooks": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"gitignore": "gitignore",
|
"gitignore": "gitignore",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
|
|
@ -115,11 +91,10 @@
|
||||||
"nixpkgs-stable": "nixpkgs-stable"
|
"nixpkgs-stable": "nixpkgs-stable"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1698227354,
|
"lastModified": 1728778939,
|
||||||
"narHash": "sha256-Fi5H9jbaQLmLw9qBi/mkR33CoFjNbobo5xWdX4tKz1Q=",
|
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "pre-commit-hooks.nix",
|
"repo": "pre-commit-hooks.nix",
|
||||||
"rev": "bd38df3d508dfcdff52cd243d297f218ed2257bf",
|
"rev": "ff68f91754be6f3427e4986d7949e6273659be1d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -134,21 +109,6 @@
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"pre-commit-hooks": "pre-commit-hooks"
|
"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",
|
"root": "root",
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,6 @@ L'encyclopédie
|
||||||
|
|
||||||
## rêveries
|
## 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.
|
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. Entrer dans le monde des morts comme Orphée ou Ulysse ?
|
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 de plus en plus fine, discutées au fil des siècles.
|
Et maîtriser un vocabulaire, des gestes, des règles affinées au fil des siècles.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue