Skip to main content

shuyi_core/
turn.rs

1//! The rules of a turn-based game as the engine's generic code sees them:
2//! a state that takes commands and answers with what happened. The game
3//! keeps its own turn loop, phases and rules, and implements
4//! [`TurnRules`] for its state; [`History`](crate::History) (replay,
5//! rewind, saving a game in progress) is written against it.
6
7use alloc::vec::Vec;
8
9/// A turn-based game's state, and the commands that change it.
10///
11/// # Contract
12///
13/// - **Deterministic.** The same state and command always give the same
14///   events and the same new state. Luck comes from a seeded RNG kept in
15///   the state ([`SimRng`](crate::SimRng)), never from outside, so a game
16///   can be rebuilt by replaying its commands.
17/// - **All or nothing.** [`apply`](Self::apply) either changes the state
18///   and returns what happened, or refuses the command with an error and
19///   changes nothing.
20/// - [`check`](Self::check) gives [`apply`](Self::apply)'s answer without
21///   changing anything, luck included.
22/// - [`legal_commands`](Self::legal_commands) lists commands
23///   [`check`](Self::check) accepts, always in the same order. A game may
24///   leave some out (when there are too many to list), and says which.
25/// - Once [`outcome`](Self::outcome) is `Some`, the game is over and
26///   [`legal_commands`](Self::legal_commands) is empty.
27pub trait TurnRules {
28    /// What a player (or an AI) asks for.
29    type Command;
30    /// What happened when a command was applied.
31    type Event;
32    /// Why a command was refused.
33    type Error;
34    /// How a game ended.
35    type Outcome;
36
37    /// Whether [`apply`](Self::apply) would accept `command`, and if not
38    /// why, without changing anything.
39    fn check(&self, command: &Self::Command) -> Result<(), Self::Error>;
40
41    /// Applies `command` and returns what happened, or refuses it and
42    /// changes nothing.
43    fn apply(&mut self, command: &Self::Command) -> Result<Vec<Self::Event>, Self::Error>;
44
45    /// The commands [`check`](Self::check) accepts now, in a fixed order.
46    fn legal_commands(&self) -> Vec<Self::Command>;
47
48    /// How the game ended, once it has.
49    fn outcome(&self) -> Option<Self::Outcome>;
50}