cache winner in Move
This commit is contained in:
@@ -17,6 +17,7 @@ impl Agent for ManualAgent {
|
|||||||
fn next_move(&mut self, _: &Board) -> Option<(usize, usize)> {
|
fn next_move(&mut self, _: &Board) -> Option<(usize, usize)> {
|
||||||
let stdin = io::stdin();
|
let stdin = io::stdin();
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
|
println!("Your turn!");
|
||||||
loop {
|
loop {
|
||||||
input.clear();
|
input.clear();
|
||||||
stdin.lock().read_line(&mut input).ok()?;
|
stdin.lock().read_line(&mut input).ok()?;
|
||||||
|
|||||||
11
src/board.rs
11
src/board.rs
@@ -201,17 +201,12 @@ impl Board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn game_winner(&self, turn: Piece) -> Option<Piece> {
|
pub fn game_winner(&self, turn: Piece) -> Option<Piece> {
|
||||||
let (white_score, black_score) = self.get_score();
|
if self.possible_moves(turn).count() > 0 {
|
||||||
let max_score = BOARD_SIZE * BOARD_SIZE;
|
// player can still make a move, there is no winner
|
||||||
let combined_score = black_score + white_score;
|
|
||||||
if max_score != combined_score {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if current player cannot make a move
|
let (white_score, black_score) = self.get_score();
|
||||||
if self.possible_moves(turn).count() > 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
match white_score.cmp(&black_score) {
|
match white_score.cmp(&black_score) {
|
||||||
Ordering::Greater => Some(Piece::White), // White win
|
Ordering::Greater => Some(Piece::White), // White win
|
||||||
Ordering::Less => Some(Piece::Black), // Black win
|
Ordering::Less => Some(Piece::Black), // Black win
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ struct Move {
|
|||||||
color: Piece,
|
color: Piece,
|
||||||
board: Board,
|
board: Board,
|
||||||
next_move: Vec<Move>,
|
next_move: Vec<Move>,
|
||||||
|
winner: Option<Piece>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Move {
|
impl Move {
|
||||||
@@ -21,22 +22,28 @@ impl Move {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.next_move.is_empty() {
|
// only compute next move if this move doesn't end the game
|
||||||
self.next_move = problem_space(&self.board, !self.color).collect();
|
if self.winner.is_none() {
|
||||||
|
if self.next_move.is_empty() {
|
||||||
|
self.next_move = problem_space(&self.board, !self.color).collect();
|
||||||
|
}
|
||||||
|
self.next_move
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|x| x.populate_next_moves(i - 1));
|
||||||
}
|
}
|
||||||
self.next_move
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|x| x.populate_next_moves(i - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(&self, agent_color: Piece, depth: usize) -> i64 {
|
fn value(&self, agent_color: Piece, depth: usize) -> i64 {
|
||||||
let mut self_value = self.captured as i64;
|
let mut self_value = self.captured as i64;
|
||||||
|
|
||||||
if self.board.game_winner(agent_color) != Some(!agent_color) {
|
if self.winner == Some(!agent_color) {
|
||||||
// if this board results in the opponent winning, MAJORLY negatively weigh this move
|
// if this board results in the opponent winning, MAJORLY negatively weigh this move
|
||||||
// NOTE! this branch isn't completely deleted because if so, the bot wouldn't make a move.
|
// NOTE! this branch isn't completely deleted because if so, the bot wouldn't make a move.
|
||||||
// We shouldn't prune branches because we still need to always react to the opponent's moves
|
// We shouldn't prune branches because we still need to always react to the opponent's moves
|
||||||
self_value = i64::MIN;
|
self_value = i64::MIN;
|
||||||
|
} else if self.winner == Some(agent_color) {
|
||||||
|
// this move results in a
|
||||||
|
self_value = i64::MAX;
|
||||||
} else if agent_color != self.color {
|
} else if agent_color != self.color {
|
||||||
self_value = -self_value;
|
self_value = -self_value;
|
||||||
}
|
}
|
||||||
@@ -81,7 +88,9 @@ impl Move {
|
|||||||
color: !color,
|
color: !color,
|
||||||
board: *board,
|
board: *board,
|
||||||
next_move: problem_space(board, color).collect(),
|
next_move: problem_space(board, color).collect(),
|
||||||
|
winner: board.game_winner(!color),
|
||||||
}],
|
}],
|
||||||
|
winner: board.game_winner(color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,6 +109,7 @@ fn problem_space(board: &Board, color: Piece) -> Box<dyn Iterator<Item = Move> +
|
|||||||
color,
|
color,
|
||||||
board,
|
board,
|
||||||
next_move: Vec::new(),
|
next_move: Vec::new(),
|
||||||
|
winner: board.game_winner(color),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ mod piece;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let player1 = complexagent::ComplexAgent::new(Piece::Black);
|
let player1 = complexagent::ComplexAgent::new(Piece::Black);
|
||||||
let player2 = complexagent::ComplexAgent::new(Piece::White);
|
// let player2 = complexagent::ComplexAgent::new(Piece::White);
|
||||||
// let player2 = agent::ManualAgent::new(Piece::White);
|
let player2 = agent::ManualAgent::new(Piece::White);
|
||||||
// let player2 = agent::RandomAgent::new(Piece::White);
|
// let player2 = agent::RandomAgent::new(Piece::White);
|
||||||
let mut game = Game::new(Box::new(player1), Box::new(player2));
|
let mut game = Game::new(Box::new(player1), Box::new(player2));
|
||||||
game.game_loop();
|
game.game_loop();
|
||||||
|
|||||||
Reference in New Issue
Block a user