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