From 5ecbdca1d720d94e5c2fcfc4553a8350104bbd34 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Mon, 1 Feb 2021 22:17:00 +0100 Subject: Added minimax --- src/main.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 3055740..d9ee527 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,19 +30,21 @@ struct Position { /// stones of the current player player: u64, /// stones of the grid - mask: u64, + mask: u64, + pub play_count: u64, } // https://github.com/PascalPons/connect4/blob/master/Position.hpp impl Position { fn new() -> Position { - Position{ player: 0, mask: 0 } + Position{ player: 0, mask: 0, play_count: 0 } } fn play(&self, col_pos: u64) -> Position { Position { - player: self.player ^ self.mask, - mask: self.mask | self.mask + Position::bottom_mask(col_pos), + player: self.player ^ self.mask, + mask: self.mask | self.mask + Position::bottom_mask(col_pos), + play_count: self.play_count + 1, } } @@ -93,6 +95,10 @@ impl Position { false } + fn is_draw(&self) -> bool { + return self.play_count == WIDTH * HEIGHT; + } + fn key(&self) -> u64 { self.player + self.mask } @@ -134,7 +140,7 @@ impl From<&[u64]> for Position { impl From<&str> for Position { fn from(s: &str) -> Self { - let it = s.chars().map(|c| c.to_digit(10).unwrap() as u64); + let it = s.chars().map(|c| c.to_digit(10).unwrap() as u64 - 1); if it.clone().any(|x| x >= WIDTH) { panic!("bad position string format \"{}\"", s); } @@ -149,6 +155,7 @@ use std::fmt; impl fmt::Debug for Position { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use Cell::*; + write!(f, "play_count: {}\n", self.play_count)?; write!(f, "{:10}{:10}{:10}\n", "position", "mask", "player")?; for y in (0..FULL_HEIGHT).rev() { for x in 0..WIDTH { @@ -283,6 +290,10 @@ mod tests { assert!(p.is_winning_play(3), "\n{:?}", p); // anti diagonal } + #[test] + fn test_is_draw() { + } + #[test] fn test_from_slice() { let p = Position::from(&[0, 1, 2][..]); @@ -314,11 +325,34 @@ mod tests { } } +fn solve(p: Position) -> i32 { + if p.is_draw() { + return 0; + } + for x in 0..WIDTH { + if p.is_valid_play(x) && p.is_winning_play(x) { + return (((WIDTH * HEIGHT + 1) as i32) - (p.play_count as i32)) / 2; + } + } + let mut best = -((WIDTH * HEIGHT) as i32); + for x in 0..WIDTH { + if !p.is_valid_play(x) { + continue + } + let score = -solve(p.play(x)); + if score > best { + best = score; + } + } + return best; +} + fn main() { - let mut p = Position::new(); - p = p.play(2); - p = p.play(2); - p = p.play(1); - p = p.play(5); - println!("{:?}", p); + let mut p = Position::from("7422341735647741166133573473242566"); + // p = p.play(2); + // p = p.play(2); + // p = p.play(1); + // p = p.play(5); + // println!("{:?}", p); + println!("{}", solve(p.clone())); } -- cgit