move.cpp (3831B)
1 #include "move.hpp" 2 #include "utils.hpp" 3 #include "utils_ui.hpp" 4 5 #include <algorithm> 6 #include <iomanip> 7 8 void Move::piece_remove(Board &board, Type type, Color color, Square square) const { 9 board.pop_piece(type, color, square); 10 11 board.xor_hash(zobrist::key_piece(type, color, square)); 12 if (type == PAWN) board.xor_hash_pawn(zobrist::key_pawn(color, square)); 13 } 14 15 void Move::piece_set(Board &board, Type type, Color color, Square square) const { 16 board.set_piece(type, color, square); 17 18 board.xor_hash(zobrist::key_piece(type, color, square)); 19 if (type == PAWN) board.xor_hash_pawn(zobrist::key_pawn(color, square)); 20 } 21 22 void Move::piece_move(Board &board, Type type, Color color, Square source, Square target) const { 23 piece_remove(board, type, color, source); 24 piece_set(board, type, color, target); 25 } 26 27 using Type::PAWN; 28 using Type::ROOK; 29 30 bool Move::make(Board &board) const { 31 static constexpr const int castling_rights[64] = { 32 // clang-format off 33 13, 15, 15, 15, 12, 15, 15, 14, 34 15, 15, 15, 15, 15, 15, 15, 15, 35 15, 15, 15, 15, 15, 15, 15, 15, 36 15, 15, 15, 15, 15, 15, 15, 15, 37 15, 15, 15, 15, 15, 15, 15, 15, 38 15, 15, 15, 15, 15, 15, 15, 15, 39 15, 15, 15, 15, 15, 15, 15, 15, 40 7, 15, 15, 15, 3, 15, 15, 11, 41 // clang-format on 42 }; 43 44 const Color color = board.get_side(), colorOther = other(color); 45 const Square source = this->source(), target = this->target(); 46 47 const auto ntarget = static_cast<Square>(this->target() + (color == Color::WHITE ? -8 : +8)); 48 49 const Type piece = board.get_square_piece_type(source); 50 51 if (!is_capture()) { 52 if (is_promote()) { 53 piece_remove(board, piece, color, source); 54 piece_set(board, promoted(), color, target); 55 } else { 56 piece_move(board, piece, color, source, target); 57 } 58 } else { 59 const Type captured = board.get_square_piece_type(target); 60 if (is_enpassant()) { 61 piece_move(board, piece, color, source, target); 62 piece_remove(board, PAWN, colorOther, ntarget); 63 } else if (is_promote()) { 64 piece_remove(board, piece, color, source); 65 piece_remove(board, captured, colorOther, target); 66 piece_set(board, promoted(), color, target); 67 } else { 68 piece_remove(board, captured, colorOther, target); 69 piece_move(board, piece, color, source, target); 70 } 71 } 72 73 board.set_enpassant(is_double() ? ntarget : Square::no_sq); 74 75 if (is_castle()) { 76 if (color == Color::WHITE) { 77 if (is_castle_king()) piece_move(board, ROOK, Color::WHITE, Square::h1, Square::f1); 78 if (is_castle_queen()) piece_move(board, ROOK, Color::WHITE, Square::a1, Square::d1); 79 } else { 80 if (is_castle_king()) piece_move(board, ROOK, Color::BLACK, Square::h8, Square::f8); 81 if (is_castle_queen()) piece_move(board, ROOK, Color::BLACK, Square::a8, Square::d8); 82 } 83 } 84 85 board.and_castle(castling_rights[this->source()] & castling_rights[this->target()]); 86 87 if (!board.is_check()) { 88 board.switch_side(); 89 return true; 90 } 91 return false; 92 } 93 94 void Move::print() const { 95 std::cout << to_coordinates(source()) << " "; 96 std::cout << to_coordinates(target()) << " "; 97 std::cout << (is_promote() ? piece::get_code(promoted()) : '.') << " "; 98 std::cout << is_double() << " "; 99 std::cout << is_enpassant() << " "; 100 std::cout << is_castle(); 101 } 102 103 Move::operator std::string() const { 104 std::string res = to_coordinates(source()) + to_coordinates(target()); 105 if (is_promote()) res += piece::get_code(promoted()); 106 return res; 107 } 108 109 std::ostream &operator<<(std::ostream &os, Move move) { return os << (std::string)move; }