This commit is contained in:
nora 2023-01-14 20:05:30 +01:00
parent d3973cc96f
commit 50f4f7edd7
2 changed files with 73 additions and 8 deletions

View file

@ -101,7 +101,7 @@ impl Connect4 {
3, 4, 6, 7, 6, 4, 3, 3, 4, 6, 7, 6, 4, 3,
2, 4, 6, 7, 6, 4, 2, 2, 4, 6, 7, 6, 4, 2,
2, 4, 6, 7, 6, 4, 2, 2, 4, 6, 7, 6, 4, 2,
3, 4, 6, 7, 6, 4, 2, 3, 4, 6, 7, 6, 4, 3,
]; ];
let score_player = |player: Player| { let score_player = |player: Player| {
@ -209,7 +209,7 @@ impl Display for Connect4 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{Player, State}; use crate::{Player, Score, State};
use super::Connect4; use super::Connect4;
@ -233,14 +233,19 @@ mod tests {
Connect4 { positions } Connect4 { positions }
} }
fn test(board: &str, state: State) { fn test_result(board: &str, state: State) {
let board = parse_board(board); let board = parse_board(board);
assert_eq!(board.result(), state); assert_eq!(board.result(), state);
} }
fn test_rate(board: &str, player: Player, score: Score) {
let board = parse_board(board);
assert_eq!(board.rate(player), score);
}
#[test] #[test]
fn draw() { fn draw() {
test( test_result(
" "
XOOOXOX XOOOXOX
XOOOXOX XOOOXOX
@ -253,7 +258,7 @@ mod tests {
#[test] #[test]
fn full_winner() { fn full_winner() {
test( test_result(
" "
XOOOXOX XOOOXOX
XOOOXOX XOOOXOX
@ -266,7 +271,7 @@ mod tests {
#[test] #[test]
fn three_rows() { fn three_rows() {
test( test_result(
" "
XXX_OOO XXX_OOO
_XXX___ _XXX___
@ -276,4 +281,60 @@ mod tests {
State::InProgress, State::InProgress,
); );
} }
#[test]
fn rate_alone_edge() {
test_rate(
"
_______
_______
_______
______X
",
Player::X,
Score(3),
)
}
#[test]
fn rate_alone_center() {
test_rate(
"
_______
_______
_______
___X___
",
Player::X,
Score(7),
)
}
#[test]
fn rate_pair_center() {
test_rate(
"
_______
_______
_______
O__X___
",
Player::X,
Score(4),
)
}
#[test]
fn rate_pair_edge() {
test_rate(
"
_______
_______
_______
O_____X
",
Player::X,
Score(0),
)
}
} }

View file

@ -71,7 +71,7 @@ impl<G: Game> PerfectPlayer<G> {
board.undo_move(pos); board.undo_move(pos);
if value >= max_value { if value > max_value {
max_value = value; max_value = value;
if depth == 0 { if depth == 0 {
self.best_move = Some(pos); self.best_move = Some(pos);
@ -107,7 +107,11 @@ impl<G: Game> GamePlayer<G> for PerfectPlayer<G> {
self.best_move = None; self.best_move = None;
self.minmax(board, this_player, Score::LOST, Score::WON, 0); self.minmax(board, this_player, Score::LOST, Score::WON, 0);
board.make_move(self.best_move.expect("could not make move"), this_player); board.make_move(
self.best_move
.unwrap_or_else(|| board.possible_moves().next().expect("cannot make move")),
this_player,
);
if self.print_time { if self.print_time {
let duration = start.elapsed(); let duration = start.elapsed();