|
@@ -27,8 +27,24 @@ enum MoveUndo {
|
|
|
//06 v := −negamax(child, depth − 1, −color)
|
|
|
//07 bestValue := max( bestValue, v )
|
|
|
//08 return bestValue
|
|
|
-pub fn search() {
|
|
|
+pub fn search(game: &Game, depth: i32) -> Move {
|
|
|
+ let mut best = i32::min_value();
|
|
|
+ let mut best_move = Move::default();
|
|
|
|
|
|
+ if depth == 0 {
|
|
|
+ return best_move;
|
|
|
+ }
|
|
|
+
|
|
|
+ let moves = generate_moves(game, game.turn);
|
|
|
+ for mov in moves {
|
|
|
+ let new_game = apply_move(game, mov);
|
|
|
+ let val = -negamax(&new_game, depth - 1);
|
|
|
+ if val > best {
|
|
|
+ best = val;
|
|
|
+ best_move = mov;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return best_move;
|
|
|
}
|
|
|
|
|
|
fn negamax(game: &Game, depth: i32) -> i32 {
|
|
@@ -36,14 +52,57 @@ fn negamax(game: &Game, depth: i32) -> i32 {
|
|
|
return evaluate(game);
|
|
|
}
|
|
|
|
|
|
- let best = i32::min_value();
|
|
|
+ let mut best = i32::min_value();
|
|
|
+ let mut best_move = Move::default();
|
|
|
let moves = generate_moves(game, game.turn);
|
|
|
for mov in moves {
|
|
|
-
|
|
|
+ let new_game = apply_move(game, mov);
|
|
|
+ let val = -negamax(&new_game, depth - 1);
|
|
|
+ if val > best {
|
|
|
+ best = val;
|
|
|
+ best_move = mov;
|
|
|
+ }
|
|
|
}
|
|
|
+ println!("bestmove {:?}", best_move);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-fn apply_move(game: &Game, mov: Move) -> Game {
|
|
|
+pub fn apply_move(game: &Game, mov: Move) -> Game {
|
|
|
+ let mut new_game = game.clone();
|
|
|
+
|
|
|
+ let side = game.turn;
|
|
|
+ let friends = game.get_all_side(side);
|
|
|
+ let others = game.get_all_side(!side);
|
|
|
+ match mov {
|
|
|
+ Move::Default { mov: mov, piece_type: pt } => {
|
|
|
+ if from_square(mov.to) | others != 0 {
|
|
|
+ new_game.apply_mask(!from_square(mov.to));
|
|
|
+ }
|
|
|
+ let moved_piece = mov.apply_to(new_game.get_piece(pt, side));
|
|
|
+ new_game.set_piece(pt, side, moved_piece);
|
|
|
+ },
|
|
|
+ Move::Castling { side, left } => {
|
|
|
+ let king = game.get_piece(KING, side);
|
|
|
+ let rook = if left {
|
|
|
+ game.get_piece(ROOK, side) & (king << 4)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ game.get_piece(ROOK, side) & (king >> 3)
|
|
|
+ };
|
|
|
+
|
|
|
+ let new_king = if left { king << 2 } else { king >> 2 };
|
|
|
+ let new_rook = if left { rook >> 3 } else { rook << 2 };
|
|
|
+
|
|
|
+ new_game.set_piece(KING, side, new_king);
|
|
|
+ new_game.set_piece(ROOK, side, new_rook);
|
|
|
+ },
|
|
|
+ Move::EnPassant { side: side, column: col } => { panic!("oh no"); },
|
|
|
+ Move::Promotion { mov: mov, promote_to: pt } => { panic!("oh no"); },
|
|
|
+ }
|
|
|
+
|
|
|
+ new_game.turn = !new_game.turn;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
+ return new_game;
|
|
|
}
|