Trait board_game::board::Board

source ·
pub trait Board: 'static + Debug + Display + Clone + Eq + Send + Sync + BoardSymmetry<Self>where
    for<'a> Self: BoardMoves<'a, Self>,{
    type Move: Debug + Display + Eq + Copy + Send + Sync;

    // Required methods
    fn next_player(&self) -> Player;
    fn is_available_move(&self, mv: Self::Move) -> Result<bool, BoardDone>;
    fn play(&mut self, mv: Self::Move) -> Result<(), PlayError>;
    fn outcome(&self) -> Option<Outcome>;
    fn can_lose_after_move() -> bool;

    // Provided methods
    fn random_available_move(
        &self,
        rng: &mut impl Rng
    ) -> Result<Self::Move, BoardDone> { ... }
    fn clone_and_play(&self, mv: Self::Move) -> Result<Self, PlayError> { ... }
    fn is_done(&self) -> bool { ... }
    fn check_done(&self) -> Result<(), BoardDone> { ... }
    fn check_can_play(&self, mv: Self::Move) -> Result<(), PlayError> { ... }
    fn play_random_available_move(
        &mut self,
        rng: &mut impl Rng
    ) -> Result<(), BoardDone> { ... }
    fn children(&self) -> Result<BoardChildrenIterator<'_, Self>, BoardDone> { ... }
}
Expand description

The main trait of this crate. Represents the state of a game.

Each game implementation is supposed to provide its own constructors to allow for customizable start positions.

Implementing Board also requires BoardSymmetry and BoardMoves to be implemented.

Additionally it can be useful to implement Hash for both the board and move types, some utility functions require those extra bounds. Do not implement Copy for the board, since the type is mutated by some of the functions and this can quickly lead to confusion.

Required Associated Types§

source

type Move: Debug + Display + Eq + Copy + Send + Sync

The type used to represent moves on this board.

Required Methods§

source

fn next_player(&self) -> Player

Return the next player to make a move. If the board is done this is the player that did not play the last move for consistency.

source

fn is_available_move(&self, mv: Self::Move) -> Result<bool, BoardDone>

Return whether the given move is available.

source

fn play(&mut self, mv: Self::Move) -> Result<(), PlayError>

Play the move mv, modifying this board.

source

fn outcome(&self) -> Option<Outcome>

The outcome of this board, is None when this games is not done yet.

source

fn can_lose_after_move() -> bool

Whether the player who plays a move can lose by playing that move. Symbolically whether b.won_by() == Some(Winner::Player(b.next_player())) can ever be true. This may be pessimistic, returning true is always correct.

Provided Methods§

source

fn random_available_move( &self, rng: &mut impl Rng ) -> Result<Self::Move, BoardDone>

Pick a random move from the available_moves with a uniform distribution. Can be overridden for better performance.

source

fn clone_and_play(&self, mv: Self::Move) -> Result<Self, PlayError>

Clone this board, play mv on it and return the new board. Can be overridden for better performance.

source

fn is_done(&self) -> bool

Whether this games is done.

source

fn check_done(&self) -> Result<(), BoardDone>

Returns

  • Err(BoardDone) if self.is_done()
  • Ok(()) otherwise.
source

fn check_can_play(&self, mv: Self::Move) -> Result<(), PlayError>

Returns

  • Err(BoardDone) if self.is_done()
  • Err(UnavailableMove) if !self.is_available_move(mv)
  • Ok(()) otherwise.
source

fn play_random_available_move( &mut self, rng: &mut impl Rng ) -> Result<(), BoardDone>

The same as self.play(self.random_available_move(rng)), but needs less error handling. Can be overridden for better performance by skipping the valid move check.

source

fn children(&self) -> Result<BoardChildrenIterator<'_, Self>, BoardDone>

The same as self.available_moves().map(|mv| self.clone_and_play(mv)), but needs less error handling. Can be overridden for better performance by skipping the valid move check.

Implementors§