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