game_solver::game

Trait Game

source
pub trait Game: Clone {
    type Move: Clone;
    type Iter<'a>: Iterator<Item = Self::Move> + 'a
       where Self: 'a;
    type MoveError;
    type Player: Player;

    const STATE_TYPE: Option<StateType>;

    // Required methods
    fn move_count(&self) -> usize;
    fn max_moves(&self) -> Option<usize>;
    fn make_move(&mut self, m: &Self::Move) -> Result<(), Self::MoveError>;
    fn possible_moves(&self) -> Self::Iter<'_>;
    fn state(&self) -> GameState<Self::Player>;
    fn player(&self) -> Self::Player;

    // Provided method
    fn find_immediately_resolvable_game(
        &self,
    ) -> Result<Option<Self>, Self::MoveError> { ... }
}
Expand description

Represents a combinatorial game.

A game has three distinct variants per game:

  • Game play type: Normal, Misere, Other
  • Game partiality type: Impartial, Partizan
  • Game player count: >0

Required Associated Constants§

Required Associated Types§

source

type Move: Clone

The type of move this game uses.

source

type Iter<'a>: Iterator<Item = Self::Move> + 'a where Self: 'a

The iterator type for possible moves.

source

type MoveError

source

type Player: Player

Required Methods§

source

fn move_count(&self) -> usize

Returns the amount of moves that have been played

source

fn max_moves(&self) -> Option<usize>

Get the max number of moves in a game, if any.

source

fn make_move(&mut self, m: &Self::Move) -> Result<(), Self::MoveError>

Makes a move.

source

fn possible_moves(&self) -> Self::Iter<'_>

Returns an iterator of all possible moves.

If possible, this function should “guess” what the best moves are first. For example, if this is for tic tac toe, it should give the middle move first. Since “better” moves would be found first, this permits more alpha/beta cutoffs.

source

fn state(&self) -> GameState<Self::Player>

Returns the current state of the game. Used for verifying initialization and is commonly called.

If Self::STATE_TYPE isn’t None, the following implementation can be used:

fn state(&self) -> GameState<Self::Player> {
    Self::STATE_TYPE.unwrap().state(self)
}
source

fn player(&self) -> Self::Player

Returns the player whose turn it is. The implementation of this should be similar to either

use game_solver::game::ZeroSumPlayer;

fn player(&self) -> Self::Player {
    if game.move_count % 2 == 0 {
       ZeroSumPlayer::One
    } else {
        ZeroSumPlayer::Two
    }
}

or

use game_solver::game::NPlayer;

fn player(&self) -> Self::Player {
    NPlayer(game.move_count % game.num_players)
}

depending on the type of game.

However, no implementation is provided because this does not keep track of the move count.

Provided Methods§

source

fn find_immediately_resolvable_game( &self, ) -> Result<Option<Self>, Self::MoveError>

Returns a reachable game in one move.

Rather, this function asks if there exists some game in the possible games set which has a resolvable, positive or negative, outcome.

This function must act in the Next player’s best interest. Positive games should have highest priority, then tied games, then lost games. Exact order of what game is returned doesn’t matter past its outcome equivalency, as the score is dependent on move count.

(If this function returns a losing game when a positive game exists in the set of immediately resolvable games, that is a violation of this function’s contract).

This function’s default implementation is quite slow, and it’s encouraged to use a custom implementation.

Object Safety§

This trait is not object safe.

Implementors§