diff --git a/card_game/src/lib.rs b/card_game/src/lib.rs index cf09d08..1613142 100644 --- a/card_game/src/lib.rs +++ b/card_game/src/lib.rs @@ -424,6 +424,33 @@ where state.undo(); } } + + // history includes cycles + let mut state_index: std::collections::HashMap<_, _> = state + .history() + .iter() + .enumerate() + .map(|(i, snapshot)| (snapshot.state().clone(), i)) + .collect(); + + // find the longest range where the start and end are the same state + while let Some(longest_range) = state + .history() + .iter() + .enumerate() + .filter_map(|(index, snapshot)| { + let &last_index = state_index.get(snapshot.state())?; + let longness = last_index - index; + (longness != 0).then_some(index..last_index) + }) + .max_by_key(|range| range.len()) + { + state.state.history.drain(longest_range); + for (i, snapshot) in state.history().iter().enumerate() { + state_index.insert(snapshot.state().clone(), i); + } + } + Some(state.state.history) } }