use std::fmt::Debug;
use crate::_internal::puzzle_traits::puzzle_traits::SemiGroupActionPuzzle;
pub(crate) struct PatternStack<TPuzzle: SemiGroupActionPuzzle> {
puzzle: TPuzzle,
stack: Vec<TPuzzle::Pattern>,
current_idx: usize,
}
impl<TPuzzle: SemiGroupActionPuzzle> Debug for PatternStack<TPuzzle> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PatternStack")
.field("puzzle", &"…")
.field("stack", &self.stack)
.field("current_idx", &self.current_idx)
.finish()
}
}
impl<TPuzzle: SemiGroupActionPuzzle> PatternStack<TPuzzle> {
pub fn new(puzzle: TPuzzle, root_pattern: TPuzzle::Pattern) -> Self {
Self {
puzzle,
stack: vec![root_pattern],
current_idx: 0,
}
}
#[must_use]
pub fn push(&mut self, transformation: &TPuzzle::Transformation) -> bool {
if self.current_idx + 1 >= self.stack.len() {
let Some(pattern) = self
.puzzle
.pattern_apply_transformation(&self.stack[self.current_idx], transformation)
else {
return false;
};
self.stack.push(pattern)
} else {
let (left, right) = self.stack.split_at_mut(self.current_idx + 1);
if !self.puzzle.pattern_apply_transformation_into(
left.last().unwrap(),
transformation,
right.first_mut().unwrap(),
) {
return false;
}
};
self.current_idx += 1;
true
}
pub fn current_pattern(&self) -> &TPuzzle::Pattern {
&self.stack[self.current_idx]
}
pub fn pop(&mut self) {
debug_assert!(self.current_idx > 0);
self.current_idx -= 1;
}
}