|
@@ -1,4 +1,3 @@
|
|
|
-use bitboard::*;
|
|
|
use movegen::*;
|
|
|
use game::Game;
|
|
|
use evaluate::*;
|
|
@@ -264,6 +263,12 @@ fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache,
|
|
|
|
|
|
let (mut val, ret) = quiescence_search(game, sc, hash, -beta, -alpha, depth - 1);
|
|
|
val = -val;
|
|
|
+
|
|
|
+ if ret {
|
|
|
+ game.undo_move(undo);
|
|
|
+ return (alpha, ret)
|
|
|
+ }
|
|
|
+
|
|
|
if val >= beta {
|
|
|
game.undo_move(undo);
|
|
|
return (beta, false);
|
|
@@ -277,111 +282,6 @@ fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache,
|
|
|
}
|
|
|
|
|
|
|
|
|
-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, piece_type: pt, captured: _ } => {
|
|
|
-
|
|
|
- if pt == KING {
|
|
|
- // invalidate castling rights
|
|
|
- new_game.castling_rights[if game.turn == BLACK { 2 } else { 0 }] = false;
|
|
|
- new_game.castling_rights[if game.turn == BLACK { 3 } else { 1 }] = false;
|
|
|
- }
|
|
|
-
|
|
|
- // invalidate castling rights
|
|
|
- if mov.from == square_from_indices(7, 0) || mov.to == square_from_indices(7, 0) {
|
|
|
- new_game.castling_rights[0] = false;
|
|
|
- }
|
|
|
- if mov.from == square_from_indices(0, 0) || mov.to == square_from_indices(0, 0) {
|
|
|
- new_game.castling_rights[1] = false;
|
|
|
- }
|
|
|
- if mov.from == square_from_indices(7, 7) || mov.to == square_from_indices(7, 7) {
|
|
|
- new_game.castling_rights[2] = false;
|
|
|
- }
|
|
|
- if mov.from == square_from_indices(0, 7) || mov.to == square_from_indices(0, 7) {
|
|
|
- new_game.castling_rights[3] = false;
|
|
|
- }
|
|
|
-
|
|
|
- // if it is a capture
|
|
|
- if from_square(mov.to) & others != 0 {
|
|
|
- let (other_piece, other_side) = game.get_square(mov.to);
|
|
|
- if let Some((ref zt, ref _zv)) = game.zobrist {
|
|
|
- let hup = zt.piece_hash(other_piece, other_side, mov.to);
|
|
|
- new_game.update_zobrist(hup);
|
|
|
- }
|
|
|
- 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);
|
|
|
-
|
|
|
- if let Some((ref zt, ref _zv)) = game.zobrist {
|
|
|
- let hup = zt.piece_hash(pt, side, mov.from) ^ zt.piece_hash(pt, side, mov.to);
|
|
|
- new_game.update_zobrist(hup);
|
|
|
- }
|
|
|
- },
|
|
|
- Move::Castling { side, left } => {
|
|
|
- // invalidate future castling rights
|
|
|
- new_game.castling_rights[if game.turn == BLACK { 2 } else { 0 }] = false;
|
|
|
- new_game.castling_rights[if game.turn == BLACK { 3 } else { 1 }] = false;
|
|
|
-
|
|
|
- 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.get_piece_mut(ROOK, side) |= new_rook;
|
|
|
- *new_game.get_piece_mut(ROOK, side) &= !rook;
|
|
|
- },
|
|
|
- Move::EnPassant { mov, beaten } => {
|
|
|
- let pawns = game.pawns(side);
|
|
|
- if let Some(ep) = game.en_passant {
|
|
|
- *new_game.get_piece_mut(PAWN, side) &= !from_square(mov.from);
|
|
|
- *new_game.get_piece_mut(PAWN, side) |= from_square(mov.to);
|
|
|
- *new_game.get_piece_mut(PAWN, !side) &= !from_square(beaten);
|
|
|
- }
|
|
|
- },
|
|
|
- Move::Promotion { mov, promote_to, captured } => {
|
|
|
- //if from_square(mov.to) & others != 0 {
|
|
|
- if let Some(pt) = captured {
|
|
|
- *new_game.get_piece_mut(pt, !side) &= !from_square(mov.to);
|
|
|
- }
|
|
|
- new_game.apply_mask(!from_square(mov.from));
|
|
|
-
|
|
|
- match promote_to {
|
|
|
- QUEEN => { *new_game.queens_mut(side) |= from_square(mov.to); }
|
|
|
- ROOK => { *new_game.rooks_mut(side) |= from_square(mov.to); }
|
|
|
- BISHOP => { *new_game.bishops_mut(side) |= from_square(mov.to); }
|
|
|
- KNIGHT => { *new_game.knights_mut(side) |= from_square(mov.to); }
|
|
|
- _ => {
|
|
|
- info!("internal error");
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- Move::Nullmove => {}
|
|
|
- }
|
|
|
-
|
|
|
- new_game.turn = !new_game.turn;
|
|
|
-
|
|
|
-
|
|
|
- if let Some((ref zt, ref zv)) = new_game.zobrist {
|
|
|
- //info!("applied {}, zobrist now {}", mov.to_string(), *zv);
|
|
|
- }
|
|
|
- return new_game;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
pub fn perft(game: &mut Game, sc: &mut SearchControl, depth: i32) -> bool {
|
|
|
let moves = generate_legal_moves(game, game.turn);
|
|
|
|