Skip to main content

turnbase_bots/
random.rs

1//! Uniform-random legal-move bot.
2
3use turnbase::{Game, PlayerId, Prng};
4
5use crate::Bot;
6
7/// Picks uniformly at random among the legal actions.
8///
9/// Deterministic given its seed: the same seed and the same sequence of
10/// positions produce the same choices, which keeps games reproducible.
11pub struct Random {
12    rng: Prng,
13}
14
15impl Random {
16    /// Creates a bot seeded from `seed`.
17    #[must_use]
18    pub const fn new(seed: u64) -> Self {
19        Self {
20            rng: Prng::new(seed),
21        }
22    }
23}
24
25impl<G: Game> Bot<G> for Random {
26    fn choose(&mut self, game: &G, state: &G::State, player: PlayerId) -> Option<G::Action> {
27        let mut actions = game.legal_actions(state, player);
28        if actions.is_empty() {
29            return None;
30        }
31        // `below` returns a value strictly less than `len` (a `usize`), so the
32        // cast back cannot truncate.
33        #[allow(clippy::cast_possible_truncation)]
34        let index = self.rng.below(actions.len() as u64) as usize;
35        Some(actions.swap_remove(index))
36    }
37}