Fied evaluator bug

master
Mark 2024-03-03 21:48:41 -08:00
parent a5e3998727
commit 7a3249e766
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
1 changed files with 93 additions and 15 deletions

View File

@ -1,4 +1,4 @@
use std::fmt::Display; use std::{fmt::Display, num::NonZeroU8};
use termion::color; use termion::color;
use crate::{Player, Symb}; use crate::{Player, Symb};
@ -47,6 +47,7 @@ impl Display for Board {
} }
} }
#[allow(dead_code)]
impl Board { impl Board {
pub fn new(current_player: Player) -> Self { pub fn new(current_player: Player) -> Self {
Self { Self {
@ -56,6 +57,14 @@ impl Board {
} }
} }
pub fn iter(&self) -> impl Iterator<Item = &Option<(Symb, Player)>> {
self.board.iter()
}
pub fn get(&self, idx: usize) -> Option<&Option<(Symb, Player)>> {
self.board.get(idx)
}
pub fn current_player(&self) -> Player { pub fn current_player(&self) -> Player {
self.current_player self.current_player
} }
@ -68,6 +77,18 @@ impl Board {
self.board.len() self.board.len()
} }
pub fn contains(&self, s: Symb) -> bool {
for i in &self.board {
if let Some(i) = i {
if i.0 == s {
return true;
}
}
}
false
}
// Place the marked symbol at the given position. // Place the marked symbol at the given position.
// Returns true for valid moves and false otherwise. // Returns true for valid moves and false otherwise.
pub fn play(&mut self, cursor: usize, symb: Symb) -> bool { pub fn play(&mut self, cursor: usize, symb: Symb) -> bool {
@ -75,12 +96,8 @@ impl Board {
Some(_) => return false, Some(_) => return false,
None => { None => {
// Check for duplicate symbols // Check for duplicate symbols
for i in &self.board { if self.contains(symb) {
if let Some(i) = i { return false;
if i.0 == symb {
return false;
}
}
} }
// Check syntax // Check syntax
@ -91,7 +108,7 @@ impl Board {
} }
let r = &self.board[cursor + 1]; let r = &self.board[cursor + 1];
if r.is_some_and(|(s, _)| s.is_binop()) { if r.is_some_and(|(s, _)| s.is_op() && !s.is_minus()) {
return false; return false;
} }
} }
@ -117,9 +134,7 @@ impl Board {
return false; return false;
} }
if l.is_some_and(|s| s.is_binop() || s.is_minus()) if l.is_some_and(|s| s.is_op()) {
|| r.is_some_and(|s| s.is_binop())
{
return false; return false;
} }
} }
@ -192,13 +207,21 @@ impl Board {
tokens.push(Token::Number(current_num * current_sgn)); tokens.push(Token::Number(current_num * current_sgn));
for op in [Token::OpMult, Token::OpDiv, Token::OpAdd, Token::OpSub] { let mut priority_level = 0;
let mut did_something;
while tokens.len() > 1 {
did_something = false;
for i in 0..tokens.len() { for i in 0..tokens.len() {
if tokens[i] == op { if match priority_level {
0 => matches!(tokens[i], Token::OpMult | Token::OpDiv),
1 => matches!(tokens[i], Token::OpAdd | Token::OpSub),
_ => false,
} {
did_something = true;
let l = &tokens[i - 1]; let l = &tokens[i - 1];
let r = &tokens[i + 1]; let r = &tokens[i + 1];
let v = match op { let v = match tokens[i] {
Token::OpAdd => l.val() + r.val(), Token::OpAdd => l.val() + r.val(),
Token::OpDiv => l.val() / r.val(), Token::OpDiv => l.val() / r.val(),
Token::OpSub => l.val() - r.val(), Token::OpSub => l.val() - r.val(),
@ -212,8 +235,63 @@ impl Board {
break; break;
} }
} }
if !did_something {
priority_level += 1;
}
} }
return Some(tokens[0].val()); Some(tokens[0].val())
}
/// Hacky method to parse a board from a string
pub fn from_string(s: &str, current_player: Player) -> Option<Self> {
if s.len() != 11 {
return None;
}
let x = s
.chars()
.filter_map(|c| {
let symb = match c {
'+' => Symb::Plus,
'-' => Symb::Minus,
'*' => Symb::Times,
'/' => Symb::Div,
'0' => Symb::Zero,
'1' => Symb::Number(NonZeroU8::new(1).unwrap()),
'2' => Symb::Number(NonZeroU8::new(2).unwrap()),
'3' => Symb::Number(NonZeroU8::new(3).unwrap()),
'4' => Symb::Number(NonZeroU8::new(4).unwrap()),
'5' => Symb::Number(NonZeroU8::new(5).unwrap()),
'6' => Symb::Number(NonZeroU8::new(6).unwrap()),
'7' => Symb::Number(NonZeroU8::new(7).unwrap()),
'8' => Symb::Number(NonZeroU8::new(8).unwrap()),
'9' => Symb::Number(NonZeroU8::new(9).unwrap()),
'_' => return Some(None),
_ => return None,
};
Some(Some((symb, current_player)))
})
.collect::<Vec<_>>();
if x.len() != 11 {
return None;
}
let mut free_spots = 11;
let mut board = [None; 11];
for i in 0..x.len() {
board[i] = x[i];
if x[i].is_some() {
free_spots -= 1;
}
}
Some(Self {
board,
free_spots,
current_player,
})
} }
} }