stellar

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

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; }