Add board to fen function
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
@@ -153,6 +155,12 @@ class ChessFFI:
|
|||||||
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)()
|
||||||
n = self._c_gen_pseudo_moves(board, buf, captures_only)
|
n = self._c_gen_pseudo_moves(board, buf, captures_only)
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
int load_fen();
|
int load_fen();
|
||||||
|
void board_to_fen(struct Board *board, char *out, size_t out_sz);
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -118,3 +123,72 @@ int load_fen(struct Board *board, const char *fen) {
|
|||||||
|
|
||||||
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';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user