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§
Required Methods§
sourcefn next_player(&self) -> Player
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.
sourcefn is_available_move(&self, mv: Self::Move) -> Result<bool, BoardDone>
fn is_available_move(&self, mv: Self::Move) -> Result<bool, BoardDone>
Return whether the given move is available.
sourcefn play(&mut self, mv: Self::Move) -> Result<(), PlayError>
fn play(&mut self, mv: Self::Move) -> Result<(), PlayError>
Play the move mv
, modifying this board.
sourcefn outcome(&self) -> Option<Outcome>
fn outcome(&self) -> Option<Outcome>
The outcome of this board, is None
when this games is not done yet.
sourcefn can_lose_after_move() -> bool
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§
sourcefn random_available_move(
&self,
rng: &mut impl Rng
) -> Result<Self::Move, BoardDone>
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.
sourcefn clone_and_play(&self, mv: Self::Move) -> Result<Self, PlayError>
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.
sourcefn check_done(&self) -> Result<(), BoardDone>
fn check_done(&self) -> Result<(), BoardDone>
Returns
Err(BoardDone)
ifself.is_done()
Ok(())
otherwise.
sourcefn check_can_play(&self, mv: Self::Move) -> Result<(), PlayError>
fn check_can_play(&self, mv: Self::Move) -> Result<(), PlayError>
Returns
Err(BoardDone)
ifself.is_done()
Err(UnavailableMove)
if!self.is_available_move(mv)
Ok(())
otherwise.
sourcefn play_random_available_move(
&mut self,
rng: &mut impl Rng
) -> Result<(), BoardDone>
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.
sourcefn children(&self) -> Result<BoardChildrenIterator<'_, Self>, BoardDone>
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.