|  | @@ -1,4 +1,3 @@
 | 
											
												
													
														|  | -use bitboard::*;
 |  | 
 | 
											
												
													
														|  |  use movegen::*;
 |  |  use movegen::*;
 | 
											
												
													
														|  |  use game::Game;
 |  |  use game::Game;
 | 
											
												
													
														|  |  use evaluate::*;
 |  |  use evaluate::*;
 | 
											
										
											
												
													
														|  | @@ -266,6 +265,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);
 |  |          let (mut val, ret) = quiescence_search(game, sc, hash, -beta, -alpha, depth - 1);
 | 
											
												
													
														|  |          val = -val;
 |  |          val = -val;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        if ret {
 | 
											
												
													
														|  | 
 |  | +            game.undo_move(undo);
 | 
											
												
													
														|  | 
 |  | +            return (alpha, ret)
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |          if val >= beta {
 |  |          if val >= beta {
 | 
											
												
													
														|  |              game.undo_move(undo);
 |  |              game.undo_move(undo);
 | 
											
												
													
														|  |              return (beta, false);
 |  |              return (beta, false);
 | 
											
										
											
												
													
														|  | @@ -279,111 +284,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 {
 |  |  pub fn perft(game: &mut Game, sc: &mut SearchControl, depth: i32) -> bool {
 | 
											
												
													
														|  |      let moves = generate_legal_moves(game, game.turn);
 |  |      let moves = generate_legal_moves(game, game.turn);
 | 
											
												
													
														|  |  
 |  |  
 |