minimax/src/agents/util/treecoords.rs
2024-03-04 23:13:07 -08:00

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)
}
}