Board cleanup
parent
39fbf31af7
commit
99b9ee975a
|
@ -1,169 +1,22 @@
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::Display;
|
||||||
|
|
||||||
use termion::color;
|
use termion::color;
|
||||||
|
|
||||||
use crate::{Player, Symb};
|
use super::{PlayerAction, TreeElement};
|
||||||
|
use crate::util::{Player, Symb};
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum Token {
|
|
||||||
Value(String),
|
|
||||||
OpAdd,
|
|
||||||
OpSub,
|
|
||||||
OpMult,
|
|
||||||
OpDiv,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone)]
|
|
||||||
pub enum TreeElement {
|
|
||||||
Partial(String),
|
|
||||||
Number(f32),
|
|
||||||
Add {
|
|
||||||
l: Box<TreeElement>,
|
|
||||||
r: Box<TreeElement>,
|
|
||||||
},
|
|
||||||
Sub {
|
|
||||||
l: Box<TreeElement>,
|
|
||||||
r: Box<TreeElement>,
|
|
||||||
},
|
|
||||||
Mul {
|
|
||||||
l: Box<TreeElement>,
|
|
||||||
r: Box<TreeElement>,
|
|
||||||
},
|
|
||||||
Div {
|
|
||||||
l: Box<TreeElement>,
|
|
||||||
r: Box<TreeElement>,
|
|
||||||
},
|
|
||||||
Neg {
|
|
||||||
r: Box<TreeElement>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for TreeElement {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Partial(s) => write!(f, "{s}")?,
|
|
||||||
Self::Number(n) => write!(f, "{n}")?,
|
|
||||||
Self::Add { l, r } => write!(f, "({l}+{r})")?,
|
|
||||||
Self::Div { l, r } => write!(f, "({l}÷{r})")?,
|
|
||||||
Self::Mul { l, r } => write!(f, "({l}×{r})")?,
|
|
||||||
Self::Sub { l, r } => write!(f, "({l}-{r})")?,
|
|
||||||
Self::Neg { r } => write!(f, "(-{r})")?,
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for TreeElement {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
Display::fmt(&self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum InterTreeElement {
|
enum InterTreeElement {
|
||||||
Unprocessed(Token),
|
Unprocessed(Token),
|
||||||
Processed(TreeElement),
|
Processed(TreeElement),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
impl TreeElement {
|
enum Token {
|
||||||
pub fn left(&self) -> Option<&TreeElement> {
|
Value(String),
|
||||||
match self {
|
OpAdd,
|
||||||
Self::Add { l, .. }
|
OpSub,
|
||||||
| Self::Sub { l, .. }
|
OpMult,
|
||||||
| Self::Mul { l, .. }
|
OpDiv,
|
||||||
| Self::Div { l, .. } => Some(&**l),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn right(&self) -> Option<&TreeElement> {
|
|
||||||
match self {
|
|
||||||
Self::Add { r, .. }
|
|
||||||
| Self::Neg { r, .. }
|
|
||||||
| Self::Sub { r, .. }
|
|
||||||
| Self::Mul { r, .. }
|
|
||||||
| Self::Div { r, .. } => Some(&**r),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn left_mut(&mut self) -> Option<&mut TreeElement> {
|
|
||||||
match self {
|
|
||||||
Self::Add { l, .. }
|
|
||||||
| Self::Sub { l, .. }
|
|
||||||
| Self::Mul { l, .. }
|
|
||||||
| Self::Div { l, .. } => Some(&mut **l),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn right_mut(&mut self) -> Option<&mut TreeElement> {
|
|
||||||
match self {
|
|
||||||
Self::Add { r, .. }
|
|
||||||
| Self::Neg { r, .. }
|
|
||||||
| Self::Sub { r, .. }
|
|
||||||
| Self::Mul { r, .. }
|
|
||||||
| Self::Div { r, .. } => Some(&mut **r),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PlayerAction {
|
|
||||||
pub symb: Symb,
|
|
||||||
pub pos: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TreeElement {
|
|
||||||
pub fn evaluate(&self) -> Option<f32> {
|
|
||||||
match self {
|
|
||||||
Self::Number(x) => Some(*x),
|
|
||||||
Self::Partial(_) => None,
|
|
||||||
Self::Add { l, r } => {
|
|
||||||
let l = l.evaluate();
|
|
||||||
let r = r.evaluate();
|
|
||||||
if let (Some(l), Some(r)) = (l, r) {
|
|
||||||
Some(l + r)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self::Mul { l, r } => {
|
|
||||||
let l = l.evaluate();
|
|
||||||
let r = r.evaluate();
|
|
||||||
if let (Some(l), Some(r)) = (l, r) {
|
|
||||||
Some(l * r)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self::Div { l, r } => {
|
|
||||||
let l = l.evaluate();
|
|
||||||
let r = r.evaluate();
|
|
||||||
if let (Some(l), Some(r)) = (l, r) {
|
|
||||||
Some(l / r)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self::Sub { l, r } => {
|
|
||||||
let l = l.evaluate();
|
|
||||||
let r = r.evaluate();
|
|
||||||
if let (Some(l), Some(r)) = (l, r) {
|
|
||||||
Some(l - r)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self::Neg { r } => {
|
|
||||||
let r = r.evaluate();
|
|
||||||
if let Some(r) = r {
|
|
||||||
Some(-r)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -299,7 +152,7 @@ impl Board {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tokenize(&self) -> Vec<Token> {
|
fn tokenize(&self) -> Vec<Token> {
|
||||||
let mut tokens = Vec::new();
|
let mut tokens = Vec::new();
|
||||||
let mut is_neg = true; // if true, - is negative. if false, subtract.
|
let mut is_neg = true; // if true, - is negative. if false, subtract.
|
||||||
let mut current_num = String::new();
|
let mut current_num = String::new();
|
||||||
|
@ -353,7 +206,9 @@ impl Board {
|
||||||
tokens
|
tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn treeify(tokens: &Vec<Token>) -> TreeElement {
|
pub fn to_tree(&self) -> TreeElement {
|
||||||
|
let tokens = self.tokenize();
|
||||||
|
|
||||||
let mut tree: Vec<_> = tokens
|
let mut tree: Vec<_> = tokens
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| InterTreeElement::Unprocessed(x.clone()))
|
.map(|x| InterTreeElement::Unprocessed(x.clone()))
|
||||||
|
@ -468,7 +323,7 @@ impl Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self) -> Option<f32> {
|
pub fn evaluate(&self) -> Option<f32> {
|
||||||
Self::treeify(&self.tokenize()).evaluate()
|
self.to_tree().evaluate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hacky method to parse a board from a string
|
/// Hacky method to parse a board from a string
|
|
@ -0,0 +1,12 @@
|
||||||
|
mod board;
|
||||||
|
mod tree;
|
||||||
|
|
||||||
|
pub use board::Board;
|
||||||
|
pub use tree::TreeElement;
|
||||||
|
|
||||||
|
use crate::Symb;
|
||||||
|
|
||||||
|
pub struct PlayerAction {
|
||||||
|
pub symb: Symb,
|
||||||
|
pub pos: usize,
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone)]
|
||||||
|
pub enum TreeElement {
|
||||||
|
Partial(String),
|
||||||
|
Number(f32),
|
||||||
|
Add {
|
||||||
|
l: Box<TreeElement>,
|
||||||
|
r: Box<TreeElement>,
|
||||||
|
},
|
||||||
|
Sub {
|
||||||
|
l: Box<TreeElement>,
|
||||||
|
r: Box<TreeElement>,
|
||||||
|
},
|
||||||
|
Mul {
|
||||||
|
l: Box<TreeElement>,
|
||||||
|
r: Box<TreeElement>,
|
||||||
|
},
|
||||||
|
Div {
|
||||||
|
l: Box<TreeElement>,
|
||||||
|
r: Box<TreeElement>,
|
||||||
|
},
|
||||||
|
Neg {
|
||||||
|
r: Box<TreeElement>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for TreeElement {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Partial(s) => write!(f, "{s}")?,
|
||||||
|
Self::Number(n) => write!(f, "{n}")?,
|
||||||
|
Self::Add { l, r } => write!(f, "({l}+{r})")?,
|
||||||
|
Self::Div { l, r } => write!(f, "({l}÷{r})")?,
|
||||||
|
Self::Mul { l, r } => write!(f, "({l}×{r})")?,
|
||||||
|
Self::Sub { l, r } => write!(f, "({l}-{r})")?,
|
||||||
|
Self::Neg { r } => write!(f, "(-{r})")?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for TreeElement {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(&self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
impl TreeElement {
|
||||||
|
pub fn left(&self) -> Option<&TreeElement> {
|
||||||
|
match self {
|
||||||
|
Self::Add { l, .. }
|
||||||
|
| Self::Sub { l, .. }
|
||||||
|
| Self::Mul { l, .. }
|
||||||
|
| Self::Div { l, .. } => Some(&**l),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn right(&self) -> Option<&TreeElement> {
|
||||||
|
match self {
|
||||||
|
Self::Add { r, .. }
|
||||||
|
| Self::Neg { r, .. }
|
||||||
|
| Self::Sub { r, .. }
|
||||||
|
| Self::Mul { r, .. }
|
||||||
|
| Self::Div { r, .. } => Some(&**r),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn left_mut(&mut self) -> Option<&mut TreeElement> {
|
||||||
|
match self {
|
||||||
|
Self::Add { l, .. }
|
||||||
|
| Self::Sub { l, .. }
|
||||||
|
| Self::Mul { l, .. }
|
||||||
|
| Self::Div { l, .. } => Some(&mut **l),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn right_mut(&mut self) -> Option<&mut TreeElement> {
|
||||||
|
match self {
|
||||||
|
Self::Add { r, .. }
|
||||||
|
| Self::Neg { r, .. }
|
||||||
|
| Self::Sub { r, .. }
|
||||||
|
| Self::Mul { r, .. }
|
||||||
|
| Self::Div { r, .. } => Some(&mut **r),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn evaluate(&self) -> Option<f32> {
|
||||||
|
match self {
|
||||||
|
Self::Number(x) => Some(*x),
|
||||||
|
Self::Partial(_) => None,
|
||||||
|
Self::Add { l, r } => {
|
||||||
|
let l = l.evaluate();
|
||||||
|
let r = r.evaluate();
|
||||||
|
if let (Some(l), Some(r)) = (l, r) {
|
||||||
|
Some(l + r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Mul { l, r } => {
|
||||||
|
let l = l.evaluate();
|
||||||
|
let r = r.evaluate();
|
||||||
|
if let (Some(l), Some(r)) = (l, r) {
|
||||||
|
Some(l * r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Div { l, r } => {
|
||||||
|
let l = l.evaluate();
|
||||||
|
let r = r.evaluate();
|
||||||
|
if let (Some(l), Some(r)) = (l, r) {
|
||||||
|
Some(l / r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Sub { l, r } => {
|
||||||
|
let l = l.evaluate();
|
||||||
|
let r = r.evaluate();
|
||||||
|
if let (Some(l), Some(r)) = (l, r) {
|
||||||
|
Some(l - r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Neg { r } => {
|
||||||
|
let r = r.evaluate();
|
||||||
|
if let Some(r) = r {
|
||||||
|
Some(-r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue