We need GameState::rewards_for_players implemented, the library currently doesn't need to specify for a singular player.
85 lines
3.2 KiB
Rust
85 lines
3.2 KiB
Rust
use crate::tree::node::RewardVal;
|
|
use std::collections::HashMap;
|
|
use std::fmt::Debug;
|
|
use std::hash::Hash;
|
|
|
|
/// Trait for the game state used in MCTS
|
|
///
|
|
/// When leveraging MCTS for your game, you must implement this trait to provide
|
|
/// the specifics for your game.
|
|
pub trait GameState: Clone + Debug {
|
|
/// The type of actions that can be taken in the game
|
|
type Action: Action;
|
|
|
|
/// The type of players in the game
|
|
type Player: Player;
|
|
|
|
/// Returns if the game state is terminal, i.e. the game is over
|
|
///
|
|
/// A game state is terminal when no other actions are possible. This can be
|
|
/// the result of a player winning, a draw, or because some other conditions
|
|
/// have been met leading to a game with no further possible states.
|
|
///
|
|
/// The default implementation returns True if `get_legal_actions()` returns
|
|
/// an empty list. It is recommended to override this for a more efficient
|
|
/// implementation if possible.
|
|
fn is_terminal(&self) -> bool {
|
|
let actions = self.get_legal_actions();
|
|
actions.len() == 0
|
|
}
|
|
|
|
/// Returns the list of legal actions for the game state
|
|
///
|
|
/// This method must return all possible actions that can be made from the
|
|
/// current game state.
|
|
fn get_legal_actions(&self) -> Vec<Self::Action>;
|
|
|
|
/// Returns the game state resulting from applying the action to the state
|
|
///
|
|
/// This function should not modify the current state directly, and
|
|
/// instead should modify a copy of the state and return that.
|
|
fn state_after_action(&self, action: &Self::Action) -> Self;
|
|
|
|
/// Returns the rewards for all players from their perspective for the game state
|
|
///
|
|
/// This evaluates the current state from the perspective of each player, and
|
|
/// returns a HashMap mapping each player to the result of this evaluation, which
|
|
/// we call the reward.
|
|
///
|
|
/// This is used in the MCTS backpropagation and simulation phases to evaluate
|
|
/// the value of a given node in the search tree.
|
|
///
|
|
/// A general rule of thumb for values are:
|
|
/// - 1.0 => a win for the player
|
|
/// - 0.5 => a draw
|
|
/// - 0.0 => a loss for the player
|
|
///
|
|
/// Other values can be used for relative wins or losses
|
|
fn rewards_for_players(&self) -> HashMap<Self::Player, RewardVal>;
|
|
|
|
/// Returns the player whose turn it is for the game state
|
|
///
|
|
/// This is used for evaluating the state, so for simultaneous games
|
|
/// consider the "current player" as the one from whose perspective we are
|
|
/// evaluating the game state from
|
|
fn get_current_player(&self) -> &Self::Player;
|
|
}
|
|
|
|
/// Trait used for actions that can be taken in a game
|
|
///
|
|
/// An action is dependent upon the specific game being defined, and includes
|
|
/// things like moves, attacks, and other decisions.
|
|
pub trait Action: Clone + Debug {}
|
|
|
|
/// Trait used for players participating in a game
|
|
pub trait Player: Clone + Debug + PartialEq + Eq + Hash {}
|
|
|
|
/// Convenience implemnentation of a Player for usize
|
|
impl Player for usize {}
|
|
|
|
/// Convenience implemnentation of a Player for char
|
|
impl Player for char {}
|
|
|
|
/// Convenience implemnentation of a Player for String
|
|
impl Player for String {}
|