diff --git a/src/fen.c-move-to-temp-migration-bitboard__fen.c b/src/fen.c-move-to-temp-migration-bitboard__fen.c new file mode 100644 index 0000000..86d3206 --- /dev/null +++ b/src/fen.c-move-to-temp-migration-bitboard__fen.c @@ -0,0 +1,175 @@ +/* fen.c - fen notation. + * + * Copyright (C) 2021 Bruno Raoult ("br") + * Licensed under the GNU General Public License v3.0 or later. + * Some rights reserved. See COPYING. + * + * You should have received a copy of the GNU General Public License along with this + * program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include +#include +#include +#include +#include + +#include + +#include "chessdefs.h" +#include "position.h" +#include "board.h" +#include "fen.h" +#include "piece.h" + +/* Starting Position : + * rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 + * After 1.e4 : + * rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1 + * After 1... c5 : + * rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2 + * After 2. Nf3: + * rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2 + * + * 1 : White uppercase + * 2 : next move (w or b) + * 3 : Castling capabilities: "-" if none, KQ/kq if white/black can castle + * on K or Q side + * 4 : en-passant: if pawn just moved 2 squares, indicate target square (e.g. + * for e2-e4 this field is e3) + * 5 : half moves since last capture or pawn advance (for 50 moves rule) + * 6 : full moves, starts at 1, increments after black move + * + */ + +// warning, we expect a valid fen input +pos_t *fen2pos(pos_t *pos, char *fen) +{ + char *p = fen; + short rank, file, skip, color, bbpiece; + piece_t piece; + board_t *board = pos->board; +# define SKIP_BLANK(p) for(;*(p) == ' '; (p)++) + + pos_clear(pos); + /* 1) get piece placement information + */ + for (rank = 7, file = 0; *p && *p != ' '; ++p) { + color = isupper(*p)? WHITE: BLACK; + char cp = toupper(*p); + switch (cp) { + case CHAR_PAWN: + bbpiece = BB_PAWN; + piece = PAWN; + goto set_square; + case CHAR_KNIGHT: + bbpiece = BB_KNIGHT; + piece = KNIGHT; + goto set_square; + case CHAR_BISHOP: + bbpiece = BB_BISHOP; + piece = BISHOP; + goto set_square; + case CHAR_ROOK: + bbpiece = BB_ROOK; + piece = ROOK; + goto set_square; + case CHAR_QUEEN: + bbpiece = BB_QUEEN; + piece = QUEEN; + goto set_square; + case CHAR_KING: + bbpiece = BB_KING; + piece = KING; + //pos->bb[color][BB_KING] = BB(file, rank); + //goto set_square; + set_square: +# ifdef DEBUG_FEN + log_i(5, "f=%d r=%d *p=%c piece=%c color=%d\n", + file, rank, *p, cp, color); +# endif + pos->bb[color][bbpiece] |= BB(file, rank); + pos->occupied[color] |= BB(file, rank); + SET_COLOR(piece, color); + board[SQ88(file, rank)].piece = piece; + board[SQ88(file, rank)].s_piece = + piece_add(pos, piece, SQ88(file, rank)); + file++; + break; + case '/': + rank--; + file = 0; + break; + default: + skip = cp - '0'; + while (skip--) { + board[SQ88(file++, rank)].piece = EMPTY; + } + } + } +# ifdef DEBUG_FEN + for (rank = 7; rank >= 0; --rank) { + for (file = 0; file < 8; ++file) { + log(5, "%02x ", board[SQ88(file, rank)].piece); + } + log(5, "\n"); + } +# endif + + /* 2) next move color + */ + SKIP_BLANK(p); + SET_COLOR(pos->turn, *p == 'w' ? WHITE : BLACK); + p++; + + /* 3) castle status + */ + SKIP_BLANK(p); + pos->castle = 0; + if (*p != '-') { + for (; *p && *p != ' '; ++p) { + switch (*p) { + case 'K': + pos->castle |= CASTLE_WK; + break; + case 'k': + pos->castle |= CASTLE_BK; + break; + case 'Q': + pos->castle |= CASTLE_WQ; + break; + case 'q': + pos->castle |= CASTLE_BQ; + break; + } + } + } + p++; + + /* 4) en passant + */ + SKIP_BLANK(p); + pos->en_passant = 0; + if (*p != '-') { + //SET_F(pos->en_passant, C2FILE(*p++)); + //SET_R(pos->en_passant, C2RANK(*p++)); + pos->en_passant = SQ88(C2FILE(*p), C2RANK(*(p+1))); + pos += 2; + } else { + p++; + } + + /* 5) half moves since last capture or pawn move and + * 6) current move number + */ + SKIP_BLANK(p); + //log_i(5, "pos=%d\n", (int)(p-fen)); + sscanf(p, "%hd %hd", &pos->clock_50, &pos->curmove); +# ifdef DEBUG_FEN + log_i(5, "50 rule=%d current move=%d\n", pos->clock_50, pos->curmove); +# endif + return pos; +}