20-add-negamax-eval-function #31

Merged
Josh merged 9 commits from 20-add-negamax-eval-function into main 2025-08-26 00:28:03 +00:00
3 changed files with 84 additions and 1 deletions
Showing only changes of commit cbe16aba8a - Show all commits

View File

@@ -62,6 +62,8 @@ FFI_SPEC = {
"load_fen": ((C.POINTER(Board), C.c_char_p), C.c_int), "load_fen": ((C.POINTER(Board), C.c_char_p), C.c_int),
"gen_pseudo_moves": ((C.POINTER(Board), C.POINTER(Move), C.c_bool), C.c_int), "gen_pseudo_moves": ((C.POINTER(Board), C.POINTER(Move), C.c_bool), C.c_int),
"apply_move_on_copy": ((C.POINTER(Board), C.POINTER(Board), Move), C.c_bool), "apply_move_on_copy": ((C.POINTER(Board), C.POINTER(Board), Move), C.c_bool),
"board_to_fen": ((C.POINTER(Board), C.c_char_p, C.c_size_t), None),
# AI Methods # AI Methods
"ai_find_best_move_with_window": ((C.POINTER(Board), C.c_int, C.c_int, C.POINTER(Move)), C.c_int) "ai_find_best_move_with_window": ((C.POINTER(Board), C.c_int, C.c_int, C.POINTER(Move)), C.c_int)
} }
@@ -151,7 +153,13 @@ class ChessFFI:
def load_fen(self, board, fen_string): def load_fen(self, board, fen_string):
return self._c_load_fen(board, fen_string.encode("ascii")) return self._c_load_fen(board, fen_string.encode("ascii"))
def board_to_fen(self, board, size=256):
buf = C.create_string_buffer(size)
self._c_board_to_fen(board, buf, size)
return buf.value.decode("ascii")
def gen_pseudo_moves(self, board, captures_only=False, cap=256): def gen_pseudo_moves(self, board, captures_only=False, cap=256):
buf = (Move * cap)() buf = (Move * cap)()

View File

@@ -1 +1,2 @@
int load_fen(); int load_fen();
void board_to_fen(struct Board *board, char *out, size_t out_sz);

View File

@@ -10,6 +10,11 @@ int square_index(int file, int rank) {
return rank*8 + file; return rank*8 + file;
} }
static const char PIECE_CH[12] = {
'P','N','B','R','Q','K',
'p','n','b','r','q','k'
};
int char_to_piece_index(char c) { int char_to_piece_index(char c) {
switch (c) { switch (c) {
case 'P': return P; case 'N': return N; case 'B': return B; case 'P': return P; case 'N': return N; case 'B': return B;
@@ -117,4 +122,73 @@ int load_fen(struct Board *board, const char *fen) {
board->occ[BOTH] = board->occ[WHITE] | board->occ[BLACK]; board->occ[BOTH] = board->occ[WHITE] | board->occ[BLACK];
return 0; return 0;
}
void board_to_fen(const struct Board *board, char *out, size_t out_sz) {
char fen[256];
char *p = fen;
// 1. Piece placement
for (int rank = 7; rank >= 0; rank--) {
int empty = 0;
for (int file = 0; file < 8; file++) {
int sq = rank * 8 + file;
char piece = 0;
for (int i = 0; i < 12; i++) {
if (board->pieces[i] & (1ULL << sq)) {
piece = PIECE_CH[i];
break;
}
}
if (piece) {
if (empty > 0) {
*p++ = '0' + empty;
empty = 0;
}
*p++ = piece;
} else {
empty++;
}
}
if (empty > 0) *p++ = '0' + empty;
if (rank > 0) *p++ = '/';
}
// 2. Side to move
*p++ = ' ';
*p++ = (board->side_to_move == WHITE) ? 'w' : 'b';
// 3. Castling rights
*p++ = ' ';
bool any = false;
if (board->castling_rights & CASTLE_WK) { *p++ = 'K'; any = true; }
if (board->castling_rights & CASTLE_WQ) { *p++ = 'Q'; any = true; }
if (board->castling_rights & CASTLE_BK) { *p++ = 'k'; any = true; }
if (board->castling_rights & CASTLE_BQ) { *p++ = 'q'; any = true; }
if (!any) *p++ = '-';
// 4. En passant
*p++ = ' ';
if (board->ep_square >= 0) {
int file = board->ep_square % 8;
int rank = board->ep_square / 8;
*p++ = 'a' + file;
*p++ = '1' + rank;
} else {
*p++ = '-';
}
// 5. Halfmove clock
p += sprintf(p, " %d", board->halfmove_clock);
// 6. Fullmove number
p += sprintf(p, " %d", board->fullmove_number);
*p = '\0';
// Copy safely into output buffer
strncpy(out, fen, out_sz);
out[out_sz - 1] = '\0';
} }