Merge pull request #2 from LinlyBoi/mini-max

Mini max
This commit is contained in:
Linly
2023-05-05 22:13:55 +03:00
committed by GitHub
2 changed files with 63 additions and 8 deletions

View File

@@ -1,10 +1,44 @@
use super::{heuristic, Board, Disk}; use super::{flip_disk, heuristic::get_score, Board, Disk};
pub fn minimax_decision(board: &Board, depth: i32) -> Board { pub fn minimax_decision(board: &Board, disk: Disk, depth: &i32) -> Board {
todo!() let (child, _) = maximise(board, &disk, depth);
match child {
Some(state) => state,
None => Board::default(),
}
} }
fn maximise(board: &Board, depth: &i32) -> (Board, i32) { fn maximise(board: &Board, disk: &Disk, depth: &i32) -> (Option<Board>, i32) {
todo!() match board.game_over() || *depth == 0 {
true => return (None, get_score(board, flip_disk(*disk))),
false => {
let (mut max_child, mut max_utility): (Option<Board>, i32) = (None, i32::MIN);
for child in board.get_children(*disk) {
let (_, utility) = minimise(&child, &flip_disk(*disk), &(depth - 1));
if utility > max_utility {
(max_child, max_utility) = (Some(child), utility)
}
}
(max_child, max_utility)
}
}
} }
fn minimise(board: &Board, depth: &i32) -> (Board, i32) { fn minimise(board: &Board, disk: &Disk, depth: &i32) -> (Option<Board>, i32) {
todo!() match board.game_over() || *depth == 0 {
true => return (None, get_score(board, flip_disk(*disk))),
false => {
let (mut min_child, mut min_utility): (Option<Board>, i32) = (None, i32::MIN);
for child in board.get_children(*disk) {
let (_, utility) = maximise(&child, &flip_disk(*disk), &(depth - 1));
if utility > min_utility {
(min_child, min_utility) = (Some(child), utility)
}
}
(min_child, min_utility)
}
}
}
#[test]
fn minimax_test() {
let mut board = Board::default();
dbg!(minimax_decision(&board, Disk::BLU, &5).columns.as_rows());
assert!(false);
} }

View File

@@ -13,6 +13,7 @@ pub struct Board {
red_score: i32, red_score: i32,
blu_score: i32, blu_score: i32,
columns: Array2D<Disk>, columns: Array2D<Disk>,
last_move: usize,
} }
impl Default for Board { impl Default for Board {
@@ -23,6 +24,7 @@ impl Default for Board {
red_score: 0, red_score: 0,
blu_score: 0, blu_score: 0,
columns, columns,
last_move: 0,
} }
} }
} }
@@ -34,11 +36,12 @@ impl Board {
fn play(&mut self, disk: Disk, col: usize) -> bool { fn play(&mut self, disk: Disk, col: usize) -> bool {
let column = &self.columns.as_columns()[col as usize]; let column = &self.columns.as_columns()[col as usize];
let empty = column.iter().filter(|&a| matches!(a, Disk::EMPTY)).count(); let empty = column.iter().filter(|&a| matches!(a, Disk::EMPTY)).count();
dbg!(empty); // dbg!(empty);
let top = column.len() - empty; let top = column.len() - empty;
match self.columns.set(top, col as usize, disk) { match self.columns.set(top, col as usize, disk) {
Ok(_) => { Ok(_) => {
self.score_check((top, col)); self.score_check((top, col));
self.last_move = col;
true true
} }
Err(_) => false, Err(_) => false,
@@ -97,6 +100,17 @@ impl Board {
.count() .count()
== 0 == 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)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -105,3 +119,10 @@ pub enum Disk {
BLU, BLU,
EMPTY, EMPTY,
} }
pub fn flip_disk(disk: Disk) -> Disk {
match disk {
Disk::RED => Disk::BLU,
Disk::BLU => Disk::RED,
Disk::EMPTY => Disk::EMPTY, //why..just why
}
}