stellar

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

board.cpp (2877B)


      1 #include <cctype>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <exception>
      5 
      6 #include "board.hpp"
      7 #include "piece.hpp"
      8 #include "utils.hpp"
      9 #include "utils_ui.hpp"
     10 #include "zobrist.hpp"
     11 
     12 namespace zobrist {
     13 
     14 /* Init arrays for Zobris hashing */
     15 U32 keys_pawn[2][64] = {0};
     16 U64 keys_piece[2][12][64] = {0};
     17 U64 keys_enpassant[64] = {0};
     18 U64 keys_castle[16] = {0};
     19 
     20 } // namespace zobrist
     21 
     22 /* Getters */
     23 
     24 Board::Board(const std::string &fen) {
     25     int file = 0, rank = 7, i = 0;
     26     for (i = 0; fen[i] != ' '; i++) {
     27         if (isalpha(fen[i])) {
     28             const piece::Piece &piece = piece::get_from_code(fen[i]);
     29             set_piece(piece.type, piece.color, static_cast<Square>(rank * 8 + file));
     30             file++;
     31         } else if (isdigit(fen[i])) {
     32             file += fen[i] - '0';
     33         } else if (fen[i] == '/') {
     34             if (file != 8) throw std::runtime_error("File is not complete");
     35             file = 0;
     36             rank--;
     37         } else {
     38             throw std::runtime_error("Invalid piece position");
     39         }
     40     }
     41 
     42     side = fen[++i] == 'w' ? WHITE : fen[i] == 'b' ? BLACK : throw std::runtime_error("Invalid player char");
     43 
     44     for (i += 2; fen[i] != ' '; i++) {
     45         if (fen[i] == 'K') castle |= Castle::WK;
     46         else if (fen[i] == 'Q')
     47             castle |= Castle::WQ;
     48         else if (fen[i] == 'k')
     49             castle |= Castle::BK;
     50         else if (fen[i] == 'q')
     51             castle |= Castle::BQ;
     52         else if (fen[i] == '-') {
     53             i++;
     54             break;
     55         } else
     56             throw std::runtime_error("Invalid castle rights");
     57     }
     58 
     59     enpassant = fen[++i] != '-' ? from_coordinates(fen.substr(i, 2)) : Square::no_sq;
     60 
     61     hash_pawn = zobrist::hash_pawn(*this);
     62     hash = zobrist::hash(*this);
     63 }
     64 
     65 std::ostream &operator<<(std::ostream &os, const Board &board) {
     66     for (int rank = 0; rank < 8; rank++) {
     67         for (int file = 0; file < 8; file++) {
     68             if (!file) os << 8 - rank << " ";
     69             auto square = static_cast<Square>((7 - rank) * 8 + file);
     70             const Type t = board.get_square_piece_type(square);
     71             if (t == NO_TYPE) {
     72                 os << ". ";
     73             } else {
     74                 const Color c = board.get_square_piece_color(square);
     75                 os << piece::get_code(t, c) << " ";
     76             }
     77         }
     78         printf("\n");
     79     }
     80     os << "  A B C D E F G H\n";
     81     os << "     Side: ";
     82     os << ((board.side == WHITE) ? "white" : "black") << "\n";
     83     os << "Enpassant: " << to_coordinates(board.enpassant) << "\n";
     84     os << "   Castle:";
     85     os << ((board.castle & Board::Castle::WK) ? 'K' : '-');
     86     os << ((board.castle & Board::Castle::WQ) ? 'Q' : '-');
     87     os << ((board.castle & Board::Castle::BK) ? 'k' : '-');
     88     os << ((board.castle & Board::Castle::BQ) ? 'q' : '-');
     89     os << "\n     Hash:" << board.hash << "\n\n";
     90 
     91     return os;
     92 }