Skip to main content

shuyi_core/bots/
determinize.rs

1//! What a bot that plans may look at: a copy of the game as its side
2//! knows it ([`Determinize`]), and how good a state is for a side
3//! ([`Evaluate`]).
4//!
5//! A bot that plans plays moves out on copies of the game. Cloning the
6//! state itself would show it the luck to come (the rolls waiting in the
7//! state's [`SimRng`](crate::SimRng)) and whatever the other sides hide.
8//! The bots that plan on copies take only games that implement
9//! [`Determinize`], so each game decides what its bots may see
10//! (ADR-0027).
11
12use super::Sides;
13
14/// A game that can make a copy of itself as one side knows it.
15pub trait Determinize: Sides + Clone {
16    /// A copy of the state as `side` knows it, with everything `side`
17    /// can't see redrawn from `seed`: the luck to come (a new
18    /// [`SimRng::new(seed)`](crate::SimRng::new)), and the other sides'
19    /// hidden things (a hand dealt again from what is left, a piece that
20    /// hasn't shown up yet removed).
21    ///
22    /// The copy must list the same [`legal_commands`](crate::TurnRules::legal_commands)
23    /// as `self`, in the same order, and accept each of them: the
24    /// [`Rollout`](crate::Rollout) and [`TurnPlan`](crate::TurnPlan) bots
25    /// check the list and panic when it differs.
26    ///
27    /// A game with no luck and nothing hidden returns `self.clone()` and
28    /// says so in a comment. A game whose difficulty lets a bot see more
29    /// says so here.
30    #[must_use]
31    fn determinize(&self, side: Self::Side, seed: u64) -> Self;
32}
33
34/// How good a state is for a side: higher is better, in whole points.
35pub trait Evaluate<R: Sides> {
36    /// How good `end` is for `side`, reached from `start` (the state the
37    /// decision began in). A score that only needs the end ignores
38    /// `start`; one that counts what was lost on the way compares the
39    /// two. A finished game scores its outcome.
40    fn score(&self, start: &R, end: &R, side: R::Side) -> i32;
41}
42
43impl<R: Sides, F: Fn(&R, &R, R::Side) -> i32> Evaluate<R> for F {
44    fn score(&self, start: &R, end: &R, side: R::Side) -> i32 {
45        self(start, end, side)
46    }
47}