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 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,13 +96,9 @@ 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 {
|
|
||||||
if i.0 == symb {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check syntax
|
// Check syntax
|
||||||
match symb {
|
match symb {
|
||||||
|
@ -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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue