#include "fen.hpp" #include "board.hpp" #include #include #include #include #include #include #include bool WHITE = true; bool BLACK = false; static void updateBitboards(Game *g) { g->PieceBitboard = 0; g->WhitePieceBitboard = 0; g->BlackPieceBitboard = 0; std::memset(g->PieceBitboards, 0, sizeof(g->PieceBitboards)); for (uint8_t i = 0; i < 64; i++) { Piece piece = g->pieces[i]; if (piece.type == NONEPIECE) { continue; } g->PieceBitboards[piece.color][piece.type] |= (1ULL << i); if (piece.color) { g->WhitePieceBitboard |= (1ULL << i); } else { g->BlackPieceBitboard |= (1ULL << i); } } g->PieceBitboard = g->WhitePieceBitboard | g->BlackPieceBitboard; } static void SetPiece(int i, PieceType type, bool color, Game *g) { if (i < 0 || i >= 64) { std::println("Fatal: piece outside board"); assert(false && "Malformed board"); exit(1); } g->pieces[i] = {.color = color, .type = type}; } static void clearBoard(Game *g) { for (auto &piece : g->pieces) { piece = {.color = false, .type = NONEPIECE}; } g->blackCastleKing = false; g->blackCastleQueen = false; g->whiteCastleKing = false; g->whiteCastleQueen = false; } void setBoardFen(const std::string &fen, Game *g) { clearBoard(g); // example fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 int file = 0; int rank = 7; Position enpassant = {}; enum parserState : std::uint8_t { BOARD, PLAYER_TO_MOVE, CASTLE, ENPASSANT, HALF_MOVE_CLOCK, FULL_MOVE_CLOCK, }; parserState parser_state = BOARD; for (uint i = 0; i < fen.length(); i++) { char c = fen[i]; if (c == ' ') { if (parser_state == BOARD) { parser_state = PLAYER_TO_MOVE; continue; } if (parser_state == PLAYER_TO_MOVE) { parser_state = CASTLE; continue; } if (parser_state == CASTLE) { parser_state = ENPASSANT; continue; } if (parser_state == ENPASSANT) { parser_state = HALF_MOVE_CLOCK; continue; } if (parser_state == HALF_MOVE_CLOCK) { parser_state = FULL_MOVE_CLOCK; continue; } } if (parser_state == ENPASSANT) { continue; } if (parser_state == CASTLE) { if (c == '-') { g->blackCastleKing = false; g->blackCastleQueen = false; g->whiteCastleKing = false; g->whiteCastleQueen = false; continue; } if (c == 'K') { g->whiteCastleKing = true; continue; } if (c == 'Q') { g->whiteCastleQueen = true; continue; } if (c == 'k') { g->blackCastleKing = true; continue; } if (c == 'q') { g->blackCastleQueen = true; continue; } } if (parser_state == PLAYER_TO_MOVE) { if (toupper(c) == 'W') { g->turn = WHITE; continue; } if (toupper(c) == 'B') { g->turn = BLACK; continue; } } if (parser_state == BOARD) { if (isdigit(c) != 0) { int move = c - '0'; file += move; if (file > 8) { std::println("Fatal: file was to big"); assert(false && "Malformed file"); exit(1); return; // malformed file } continue; } if (c == '/') { file = 0; rank--; if (rank < 0) { std::println("Fatal: rank was to big"); assert(false && "Malformed rank"); exit(1); return; // malformed rank } continue; }; if (toupper(c) == 'N') { SetPiece((rank * 8) + file, KNIGHT, isupper(c) != 0, g); file++; continue; }; if (toupper(c) == 'R') { SetPiece((rank * 8) + file, ROOK, isupper(c) != 0, g); file++; continue; } if (toupper(c) == 'Q') { SetPiece((rank * 8) + file, QUEEN, isupper(c) != 0, g); file++; continue; } if (toupper(c) == 'B') { SetPiece((rank * 8) + file, BISHOP, isupper(c) != 0, g); file++; continue; } if (toupper(c) == 'P') { SetPiece((rank * 8) + file, PAWN, isupper(c) != 0, g); file++; continue; } if (toupper(c) == 'K') { SetPiece((rank * 8) + file, KING, isupper(c) != 0, g); file++; continue; } } break; } g->enPassant = enpassant; updateBitboards(g); }