Fied evaluator bug
parent
a5e3998727
commit
7a3249e766
106
src/board.rs
106
src/board.rs
|
@ -1,4 +1,4 @@
|
|||
use std::fmt::Display;
|
||||
use std::{fmt::Display, num::NonZeroU8};
|
||||
use termion::color;
|
||||
|
||||
use crate::{Player, Symb};
|
||||
|
@ -47,6 +47,7 @@ impl Display for Board {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Board {
|
||||
pub fn new(current_player: Player) -> 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 {
|
||||
self.current_player
|
||||
}
|
||||
|
@ -68,6 +77,18 @@ impl Board {
|
|||
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.
|
||||
// Returns true for valid moves and false otherwise.
|
||||
pub fn play(&mut self, cursor: usize, symb: Symb) -> bool {
|
||||
|
@ -75,13 +96,9 @@ impl Board {
|
|||
Some(_) => return false,
|
||||
None => {
|
||||
// Check for duplicate symbols
|
||||
for i in &self.board {
|
||||
if let Some(i) = i {
|
||||
if i.0 == symb {
|
||||
if self.contains(symb) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check syntax
|
||||
match symb {
|
||||
|
@ -91,7 +108,7 @@ impl Board {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -117,9 +134,7 @@ impl Board {
|
|||
return false;
|
||||
}
|
||||
|
||||
if l.is_some_and(|s| s.is_binop() || s.is_minus())
|
||||
|| r.is_some_and(|s| s.is_binop())
|
||||
{
|
||||
if l.is_some_and(|s| s.is_op()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -192,13 +207,21 @@ impl Board {
|
|||
|
||||
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() {
|
||||
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 r = &tokens[i + 1];
|
||||
|
||||
let v = match op {
|
||||
let v = match tokens[i] {
|
||||
Token::OpAdd => l.val() + r.val(),
|
||||
Token::OpDiv => l.val() / r.val(),
|
||||
Token::OpSub => l.val() - r.val(),
|
||||
|
@ -212,8 +235,63 @@ impl Board {
|
|||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue