core_rust/core/simulation/
simulator.rs

1use crate::core::game::*;
2use crate::core::simulation::*;
3use game_logic::Game;
4use game_variables::GameVars;
5use mapper::Mapper;
6use state::State;
7use utils::actions::Action;
8
9/// Indicates whether a simulator operates on ground or abstract states.
10pub enum SimulatorType {
11    Ground,
12    Abstract,
13}
14
15/// Minimal interface for pluggable simulators used by MCTS.
16pub trait Simulator {
17    /// Simulate one step from `state` with `action`, returning the next state and game vars.
18    fn simulate(&self, state: &State, action: Action) -> (State, GameVars);
19
20    /// Whether this simulator works at the ground or abstract level.
21    fn simulator_type(&self) -> SimulatorType;
22
23    /// Transform a ground state into the appropriate simulator’s initial state.
24    fn get_initial_state(&self, state: State) -> State;
25}
26
27impl Simulator for Box<dyn Simulator> {
28    fn simulate(&self, state: &State, action: Action) -> (State, GameVars) {
29        (**self).simulate(state, action)
30    }
31
32    fn simulator_type(&self) -> SimulatorType {
33        (**self).simulator_type()
34    }
35
36    fn get_initial_state(&self, state: State) -> State {
37        (**self).get_initial_state(state)
38    }
39}
40
41/// Simulator that steps the ground MDP directly.
42#[derive(Debug, Clone)]
43pub struct GroundSim {
44    game: Game,
45}
46
47impl GroundSim {
48    pub fn new(game: &Game) -> Self {
49        GroundSim { game: game.clone() }
50    }
51}
52
53impl Simulator for GroundSim {
54    fn simulate(&self, state: &State, action: Action) -> (State, GameVars) {
55        let (s, vars) = self.game.simulate(state, &action).unwrap();
56        (s, vars)
57    }
58
59    fn simulator_type(&self) -> SimulatorType {
60        SimulatorType::Ground
61    }
62
63    fn get_initial_state(&self, state: State) -> State {
64        state
65    }
66}
67
68/// Simulator that maps abstract actions to ground actions via a `Mapper`.
69#[derive(Debug, Clone)]
70pub struct AbstractSim {
71    game: Game,
72    mapper: Mapper,
73}
74
75impl AbstractSim {
76    pub fn new(game: &Game, mapper: Mapper) -> Self {
77        AbstractSim {
78            game: game.clone(),
79            mapper,
80        }
81    }
82}
83
84impl Simulator for AbstractSim {
85    fn simulate(&self, state: &State, action: Action) -> (State, GameVars) {
86        // Map abstract action to ground, simulate, and lift back
87        let (ground_state, ground_action) =
88            self.mapper.abstract_state_action_to_ground(state, action);
89        let (new_ground_state, vars) = self.game.simulate(&ground_state, &ground_action).unwrap();
90        let abs_state = self.mapper.ground_state_to_abstract(&new_ground_state);
91        (abs_state, vars)
92    }
93
94    fn simulator_type(&self) -> SimulatorType {
95        SimulatorType::Abstract
96    }
97
98    fn get_initial_state(&self, state: State) -> State {
99        self.mapper.ground_state_to_abstract(&state)
100    }
101}