138 lines
2.4 KiB
Rust
138 lines
2.4 KiB
Rust
use std::fmt::{Debug, Display};
|
|
|
|
use crate::board::TreeElement;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum TreeDir {
|
|
Right,
|
|
Left,
|
|
This,
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub struct TreeCoords {
|
|
len: usize,
|
|
coords: [TreeDir; 4],
|
|
inversion: [bool; 4],
|
|
}
|
|
|
|
impl Display for TreeCoords {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
if self.is_inverted() {
|
|
write!(f, "-")?
|
|
} else {
|
|
write!(f, "+")?
|
|
}
|
|
|
|
for c in self.coords {
|
|
match c {
|
|
TreeDir::Left => write!(f, "L")?,
|
|
TreeDir::Right => write!(f, "R")?,
|
|
TreeDir::This => break,
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Debug for TreeCoords {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
Display::fmt(self, f)
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
impl TreeCoords {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
len: 0,
|
|
coords: [TreeDir::This; 4],
|
|
inversion: [false; 4],
|
|
}
|
|
}
|
|
|
|
pub fn push(&mut self, dir: TreeDir, invert: bool) {
|
|
if self.len == 4 || dir == TreeDir::This {
|
|
return;
|
|
}
|
|
|
|
self.coords[self.len] = dir;
|
|
self.inversion[self.len] = invert;
|
|
self.len += 1;
|
|
}
|
|
|
|
pub fn pop(&mut self) -> Option<(TreeDir, bool)> {
|
|
if self.len == 0 {
|
|
return None;
|
|
}
|
|
|
|
self.len -= 1;
|
|
let dir = self.coords[self.len];
|
|
let inv = self.inversion[self.len];
|
|
self.coords[self.len] = TreeDir::This;
|
|
self.inversion[self.len] = false;
|
|
Some((dir, inv))
|
|
}
|
|
|
|
pub fn is_inverted(&self) -> bool {
|
|
if self.len == 0 {
|
|
false
|
|
} else {
|
|
self.inversion[self.len - 1]
|
|
}
|
|
}
|
|
|
|
pub fn get_from<'a>(&self, mut tree: &'a TreeElement) -> Option<&'a TreeElement> {
|
|
for i in 0..self.len {
|
|
match &self.coords[i] {
|
|
TreeDir::Left => {
|
|
if let Some(t) = tree.left() {
|
|
tree = t
|
|
} else {
|
|
return None;
|
|
}
|
|
}
|
|
|
|
TreeDir::Right => {
|
|
if let Some(t) = tree.right() {
|
|
tree = t
|
|
} else {
|
|
return None;
|
|
}
|
|
}
|
|
|
|
TreeDir::This => return Some(tree),
|
|
}
|
|
}
|
|
|
|
Some(tree)
|
|
}
|
|
|
|
pub fn get_from_mut<'a>(&self, mut tree: &'a mut TreeElement) -> Option<&'a mut TreeElement> {
|
|
for i in 0..self.len {
|
|
match &self.coords[i] {
|
|
TreeDir::Left => {
|
|
if let Some(t) = tree.left_mut() {
|
|
tree = t
|
|
} else {
|
|
return None;
|
|
}
|
|
}
|
|
|
|
TreeDir::Right => {
|
|
if let Some(t) = tree.right_mut() {
|
|
tree = t
|
|
} else {
|
|
return None;
|
|
}
|
|
}
|
|
|
|
TreeDir::This => return Some(tree),
|
|
}
|
|
}
|
|
|
|
Some(tree)
|
|
}
|
|
}
|