stellar

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

commit 81a01aa0657d9d75a49aba55ae606d5da5e79ff9
parent f6d0bb3f447b3ca3864ee1c2d0da0b532a561be0
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Wed, 21 Sep 2022 23:41:50 +0200

CBoard_fromFEN() function

Diffstat:
M.clang-format | 2+-
Msrc/engine.c | 105++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 97 insertions(+), 10 deletions(-)

diff --git a/.clang-format b/.clang-format @@ -16,7 +16,7 @@ AllowAllConstructorInitializersOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortEnumsOnASingleLine: true AllowShortBlocksOnASingleLine: true -AllowShortCaseLabelsOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: All AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: Never diff --git a/src/engine.c b/src/engine.c @@ -1,9 +1,24 @@ +#include <ctype.h> #include <stdio.h> #include <string.h> #include <cii/assert.h> #include <cii/except.h> #include <cii/mem.h> + +/* DEBUGGING */ + +// FEN debug positions +#define empty_board "8/8/8/8/8/8/8/8 w - - " +#define start_position \ + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 " +#define tricky_position \ + "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1 " +#define killer_position \ + "rnbqkb1r/pp1p1pPp/8/2p1pP2/1P1P4/3P3P/P1P1P3/RNBQKBNR w KQkq e6 0 1" +#define cmk_position \ + "r2q1rk1/ppp2ppp/2n1bn2/2b1p3/3pP3/3P1NPP/PPP1NPB1/R1BQ1RK1 b - - 0 9 " + /* DEFINITIONS */ // useful macros @@ -156,6 +171,14 @@ struct Piece_T Pieces[2][6] = { }; // clang-format on +Piece_T Piece_fromCode(char code) { + int color = (isupper(code)) ? WHITE : BLACK; + for (int i = 0; i < 6; i++) + if (Pieces[color][i].code == code) + return &Pieces[color][i]; + return NULL; +} + enum enumCastle { WK = 1, WQ = 2, BK = 4, BQ = 8 }; typedef enum enumCastle eCastle; @@ -181,19 +204,76 @@ struct CBoard_T Cboard_new = { }; // clang-format on -U64 board_getPieceSet(CBoard_T self, Piece_T piece) { +U64 CBoard_getPieceSet(CBoard_T self, Piece_T piece) { return self->pieceBB[Piece_color(piece)] & self->pieceBB[Piece_color(piece)]; } -U64 board_getWhitePawns(CBoard_T self) { +U64 CBoard_getWhitePawns(CBoard_T self) { return self->pieceBB[PAWN] & self->pieceBB[WHITE]; } -U64 board_getBlackPawns(CBoard_T self) { +U64 CBoard_getBlackPawns(CBoard_T self) { return self->pieceBB[PAWN] & self->pieceBB[BLACK]; } -U64 board_getPawns(CBoard_T self, eColor color) { +U64 CBoard_getPawns(CBoard_T self, eColor color) { return self->pieceBB[PAWN] & self->pieceBB[color]; } +/* ... */ + +CBoard_T CBoard_fromFEN(CBoard_T board, char *fen) { + if (!board) + NEW(board); + + memset(board, C64(0), sizeof(*board)); + + board->side = -1; + board->enpassant = no_sq; + board->castle = 0; + + int file = 0, rank = 7; + for (Piece_T piece; *fen != ' '; fen++) { + int square = rank * 8 + file; + if (isalpha(*fen)) { + if (!(piece = Piece_fromCode(*fen))) + assert(0); + bit_set(board->colorBB[piece->color], square); + bit_set(board->pieceBB[piece->piece], square); + file++; + } else if (isdigit(*fen)) { + file += *fen - '0'; + } else if (*fen == '/') { + file = 0; + rank--; + } else + assert(0); + } + + fen++; + if (*fen == 'w') + board->side = WHITE; + else if (*fen == 'b') + board->side = BLACK; + else + assert(0); + + for (fen += 2; *fen != ' '; fen++) { + switch (*fen) { + case 'K': board->castle |= WK; break; + case 'Q': board->castle |= WQ; break; + case 'k': board->castle |= BK; break; + case 'q': board->castle |= BQ; break; + case '-': break; + default: assert(0); + } + } + + fen++; + if (*fen != '-') { + board->enpassant = (*(fen + 1) - '1') * 8 + (*fen - 'a'); + } + + return board; +} + void CBoard_print(CBoard_T self) { for (int rank = 0; rank < 8; rank++) { for (int file = 0; file < 8; file++) { @@ -225,14 +305,12 @@ void CBoard_print(CBoard_T self) { printf(" A B C D E F G H\n"); printf(" Side: %s\n", (self->side == WHITE) ? "white" : "black"); printf("Enpassant: %s\n", square_to_coordinates[self->enpassant]); - printf(" Castling: %c%c%c%c\n", (self->castle & WK) ? '-' : ' ', - (self->castle & WQ) ? '-' : ' ', (self->castle & BK) ? '-' : ' ', - (self->castle & BQ) ? '-' : ' '); + printf(" Castling: %c%c%c%c\n", (self->castle & WK) ? 'K' : '-', + (self->castle & WQ) ? 'Q' : '-', (self->castle & BK) ? 'k' : '-', + (self->castle & BQ) ? 'q' : '-'); printf("\n"); } -/* ... */ - void bitboard_print(U64 bitboard) { for (int rank = 0; rank < 8; rank++) { for (int file = 0; file < 8; file++) { @@ -564,5 +642,14 @@ int main(void) { CBoard_print(&Cboard_new); + CBoard_T board; + NEW(board); + CBoard_print(CBoard_fromFEN(board, empty_board)); + CBoard_print(CBoard_fromFEN(board, start_position)); + CBoard_print(CBoard_fromFEN(board, tricky_position)); + CBoard_print(CBoard_fromFEN(board, killer_position)); + CBoard_print(CBoard_fromFEN(board, cmk_position)); + FREE(board); + return 0; }