Files
oxidised4/src/gamedata/mod.rs
2023-05-06 22:26:41 +03:00

130 lines
3.7 KiB
Rust

pub mod algorithms;
mod heuristic;
mod indices;
mod score_checkers;
#[cfg(test)]
mod tests;
use array2d::Array2D;
pub use indices::*;
#[derive(Clone)]
pub struct Board {
p1_score: i32,
p2_score: i32,
columns: Array2D<Disk>,
pub last_move: i32,
}
impl Default for Board {
fn default() -> Self {
let columns = Array2D::filled_with(Disk::EMPTY, 6, 7);
Self {
p1_score: 0,
p2_score: 0,
columns,
last_move: 0,
}
}
}
impl Board {
pub fn getscore(&self) -> (i32, i32) {
(self.p1_score, self.p2_score)
}
pub fn play(&mut self, disk: Disk, col: usize) -> bool {
let column = &self.columns.as_columns()[col];
let empty = column.iter().filter(|&a| matches!(a, Disk::EMPTY)).count();
// dbg!(empty);
let top = column.len() - empty;
match self.columns.set(top, col, disk) {
Ok(_) => {
self.score_check((top, col));
self.last_move = col as i32;
//dbg!(self.p1_score, self.p2_score);
true
}
Err(_) => false,
}
}
fn score_check(&mut self, index: (usize, usize)) {
use score_checkers::*;
let moves = get_legal_moves(
&index,
(self.columns.num_rows(), self.columns.num_columns()),
);
match self.columns.get(index.0, index.1) {
Some(disk) => match disk {
Disk::P1 => {
for _move in moves {
let mut consecutive = scan(&self.columns, &index, _move.clone(), 4);
if consecutive < 4 {
consecutive += scan(
&self.columns,
&index,
flip_direction(_move),
4 - consecutive + 1,
)
}
if consecutive - 1 == 4 {
self.p1_score += 1
}
}
}
Disk::P2 => {
for _move in moves {
let mut consecutive = scan(&self.columns, &index, _move.clone(), 4);
if consecutive < 4 {
consecutive += scan(
&self.columns,
&index,
flip_direction(_move),
4 - consecutive + 1,
)
}
if consecutive - 1 == 4 {
self.p2_score += 1
}
}
}
Disk::EMPTY => (),
},
None => (),
}
}
pub fn game_over(&self) -> bool {
self.columns
.as_row_major()
.iter()
.filter(|&d| matches!(d, &Disk::EMPTY))
.count()
== 0
}
fn get_children(&self, disk: Disk) -> Vec<Board> {
let mut children: Vec<Board> = vec![];
for column in 0..self.columns.num_columns() {
let mut child = self.clone();
match child.play(disk, column) {
true => children.push(child),
false => {}
}
}
children
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Disk {
P1,
P2,
EMPTY,
}
pub fn flip_disk(disk: Disk) -> Disk {
match disk {
Disk::P1 => Disk::P2,
Disk::P2 => Disk::P1,
Disk::EMPTY => Disk::EMPTY, //why..just why
}
}