diff --git a/card_game/src/lib.rs b/card_game/src/lib.rs index 44a82c3..1a30f3f 100644 --- a/card_game/src/lib.rs +++ b/card_game/src/lib.rs @@ -331,14 +331,32 @@ where config: G::Config, state: SessionState, } -#[derive(Clone, Eq, Hash, PartialEq)] +#[derive(Clone)] +pub struct StateSnapshot +where + G::Instruction: Clone, +{ + state: G, + instruction: G::Instruction, +} +impl StateSnapshot +where + G::Instruction: Clone, +{ + pub const fn state(&self) -> &G { + &self.state + } + pub const fn instruction(&self) -> &G::Instruction { + &self.instruction + } +} +#[derive(Clone)] pub struct SessionState where G::Instruction: Clone, { - seed: G, state: G, - history: Vec, + history: Vec>, } impl SessionState where @@ -346,7 +364,6 @@ where { fn new(state: G) -> Self { Self { - seed: state.clone(), state, history: Vec::new(), } @@ -381,7 +398,7 @@ where pub const fn config(&self) -> &G::Config { &self.config } - pub fn history(&self) -> &[G::Instruction] { + pub fn history(&self) -> &[StateSnapshot] { &self.state.history } pub fn undo(&mut self) { @@ -401,7 +418,7 @@ where pub fn is_win(&self) -> bool { self.state.is_win() } - pub fn is_winnable(&self) -> Option> { + pub fn is_winnable(&self) -> Option>> { let mut state_moves = std::collections::HashMap::new(); let mut state = self.clone(); while !state.is_win() { @@ -456,19 +473,16 @@ where ) { match instruction { SessionInstruction::Undo => { - // replay the entire history of the game except one move - self.history.pop(); - let mut inner_stats = G::Stats::default(); - let mut state = self.seed.clone(); - for instruction in &self.history { - state.process_instruction(&mut inner_stats, config, instruction.clone()); + if let Some(snapshot) = self.history.pop() { + self.state = snapshot.state; + stats.increment_undos(); } - self.state = state; - stats.inner_stats = inner_stats; - stats.increment_undos(); } SessionInstruction::InnerInstruction(instruction) => { - self.history.push(instruction.clone()); + self.history.push(StateSnapshot { + state: self.state.clone(), + instruction: instruction.clone(), + }); self.state .process_instruction(&mut stats.inner_stats, config, instruction); }