stellar

UCI Chess engine written in C++20
git clone git://git.dimitrijedobrota.com/stellar.git
Log | Files | Refs | README | LICENSE |

move.cpp (4096B)


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