Board cleanup
parent
39fbf31af7
commit
99b9ee975a
|
@ -1,169 +1,22 @@
|
|||
use std::fmt::{Debug, Display};
|
||||
use std::fmt::Display;
|
||||
|
||||
use termion::color;
|
||||
|
||||
use crate::{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)
|
||||
}
|
||||
}
|
||||
use super::{PlayerAction, TreeElement};
|
||||
use crate::util::{Player, Symb};
|
||||
|
||||
enum InterTreeElement {
|
||||
Unprocessed(Token),
|
||||
Processed(TreeElement),
|
||||
}
|
||||
|
||||
#[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 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(Debug, PartialEq, Clone)]
|
||||
enum Token {
|
||||
Value(String),
|
||||
OpAdd,
|
||||
OpSub,
|
||||
OpMult,
|
||||
OpDiv,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -299,7 +152,7 @@ impl Board {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn tokenize(&self) -> Vec<Token> {
|
||||
fn tokenize(&self) -> Vec<Token> {
|
||||
let mut tokens = Vec::new();
|
||||
let mut is_neg = true; // if true, - is negative. if false, subtract.
|
||||
let mut current_num = String::new();
|
||||
|
@ -353,7 +206,9 @@ impl Board {
|
|||
tokens
|
||||
}
|
||||
|
||||
pub fn treeify(tokens: &Vec<Token>) -> TreeElement {
|
||||
pub fn to_tree(&self) -> TreeElement {
|
||||
let tokens = self.tokenize();
|
||||
|
||||
let mut tree: Vec<_> = tokens
|
||||
.iter()
|
||||
.map(|x| InterTreeElement::Unprocessed(x.clone()))
|
||||
|
@ -468,7 +323,7 @@ impl Board {
|
|||
}
|
||||
|
||||
pub fn evaluate(&self) -> Option<f32> {
|
||||
Self::treeify(&self.tokenize()).evaluate()
|
||||
self.to_tree().evaluate()
|
||||
}
|
||||
|
||||
/// 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