From a49c6a1cdc8b3d3a1f71f5254f1ca314c9550b0d Mon Sep 17 00:00:00 2001 From: Naftali Harris Date: Fri, 23 Nov 2012 17:12:08 -0800 Subject: [PATCH] Implemented .fen reading --- games/fischer | Bin 148 -> 0 bytes games/fischer.fen | 1 + games/promotion | Bin 144 -> 0 bytes games/startpos.fen | 1 + src/bitboard.h | 5 ++ src/features.h | 2 +- src/fenio.c | 186 +++++++++++++++++++++++++++++++++++++++++++++ src/frontend.c | 13 +++- 8 files changed, 203 insertions(+), 5 deletions(-) delete mode 100644 games/fischer create mode 100644 games/fischer.fen delete mode 100644 games/promotion create mode 100644 games/startpos.fen create mode 100644 src/fenio.c diff --git a/games/fischer b/games/fischer deleted file mode 100644 index 48de30ea71f85486bfca65bb89f65779cf41e988..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmZQz292gjYh(QI+0TW6<@-c%1T)<^B!;Z%) q7EtpX7}7px0{ImzK$>O3OY`YseM}Ma{{L5~D`gO2;Adb3Y6Jk#2@@{> diff --git a/games/fischer.fen b/games/fischer.fen new file mode 100644 index 0000000..cca02ed --- /dev/null +++ b/games/fischer.fen @@ -0,0 +1 @@ +r2q1rk1/pp2ppbp/1np2np1/2Q3B1/3PP1b1/2N2N2/PP3PPP/3RKB1R b K - 6 11 diff --git a/games/promotion b/games/promotion deleted file mode 100644 index 7922f9cee98436064dbbf30c24cb78198788d606..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmZQzWB>yJ2n8cSTn-oqL_?K1K*bnUpbRLb;)Kd)Vn}BIn$Z9i&1Wc2XOIB$9Uubv R<`Dk-a;O3zHNg?Y1^^$G2j>6) diff --git a/games/startpos.fen b/games/startpos.fen new file mode 100644 index 0000000..f9c9ce2 --- /dev/null +++ b/games/startpos.fen @@ -0,0 +1 @@ +rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 diff --git a/src/bitboard.h b/src/bitboard.h index af959e7..5e83a2f 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -1,6 +1,9 @@ // bitboard.h // defs for the bitboard +#ifndef _BITBOARD_H +#define _BITBOARD_H + // if unsigned char index is the position of a piece on linboard, then // index & FILEMASK is the file of the piece, and // index >> ROWSHIFT is the row of the piece @@ -93,3 +96,5 @@ const uint64_t notlinboard[64] = { 0xbfffffffffffffff, 0x7fffffffffffffff, }; + +#endif diff --git a/src/features.h b/src/features.h index 641b75e..ef5a96c 100644 --- a/src/features.h +++ b/src/features.h @@ -3,7 +3,7 @@ // Definitions -#define _PRINT_DEFS +//#define _PRINT_DEFS //#define _DEBUG //#define _XBOARD diff --git a/src/fenio.c b/src/fenio.c new file mode 100644 index 0000000..47c1642 --- /dev/null +++ b/src/fenio.c @@ -0,0 +1,186 @@ +// fenio.c +// converts between .fen format and the position struct + +#include +#include +#include + +#include "position.h" +#include "position.c" +#include "bitboard.h" + +// reads a fen string into an alloc'd position struct +// destroys the fen string, no freeing done +// XXX: Need to take care of the history list externally. +void fen2pos(struct position *pos, char *fen) +{ + // Clear the position + memset(pos, 0, sizeof(struct position)); + + // Figure out piece placements + char *space = " "; + char *saveptr1; + char *pieces = strtok_r(fen, space, &saveptr1); + + char *slash = "/"; + char *saveptr2; + char *pieces_temp = pieces; + for(int i = 7; i >= 0; i--) + { + char *row = strtok_r(pieces_temp, slash, &saveptr2); + int j = 0; + for(int k = 0; row[k] != '\0'; k++) + { + char c = row[k]; + switch(c) + { + case 'K': + pos->wking |= board[i][j]; + pos->score += KING_VAL; + j += 1; + break; + case 'k': + pos->bking |= board[i][j]; + pos->score -= KING_VAL; + j += 1; + break; + case 'Q': + pos->wqueens |= board[i][j]; + pos->score += QUEEN_VAL; + pos->tot_mat += QUEEN_VAL; + j += 1; + break; + case 'q': + pos->bqueens |= board[i][j]; + pos->score -= QUEEN_VAL; + pos->tot_mat += QUEEN_VAL; + j += 1; + break; + case 'R': + pos->wrooks |= board[i][j]; + pos->score += ROOK_VAL; + pos->tot_mat += ROOK_VAL; + j += 1; + break; + case 'r': + pos->brooks |= board[i][j]; + pos->score -= ROOK_VAL; + pos->tot_mat += ROOK_VAL; + j += 1; + break; + case 'B': + pos->wbishops |= board[i][j]; + pos->score += BISHOP_VAL; + pos->tot_mat += BISHOP_VAL; + j += 1; + break; + case 'b': + pos->bbishops |= board[i][j]; + pos->score -= BISHOP_VAL; + pos->tot_mat += BISHOP_VAL; + j += 1; + break; + case 'N': + pos->wknights |= board[i][j]; + pos->score += KNIGHT_VAL; + pos->tot_mat += KNIGHT_VAL; + j += 1; + break; + case 'n': + pos->bknights |= board[i][j]; + pos->score -= KNIGHT_VAL; + pos->tot_mat += KNIGHT_VAL; + j += 1; + break; + case 'P': + pos->wpawns |= board[i][j]; + pos->score += PAWN_VAL; + pos->tot_mat += PAWN_VAL; + j += 1; + break; + case 'p': + pos->bpawns |= board[i][j]; + pos->score -= PAWN_VAL; + pos->tot_mat += PAWN_VAL; + j += 1; + break; + default: // a number + j += (c - '1' + 1); + break; + } + } + pieces_temp = NULL; + } + + // Figure out who is to move + char *tomove = strtok_r(NULL, space, &saveptr1); + switch(tomove[0]) + { + case 'w': + pos->tomove = WHITE; + pos->towait = BLACK; + break; + default: + pos->tomove = BLACK; + pos->towait = WHITE; + break; + } + + // Figure out castling + pos->perm_castling = NONE; + char *castling = strtok_r(NULL, space, &saveptr1); + for(int k = 0; castling[k] != '\0'; k++) + { + char c = castling[k]; + switch(c) + { + case 'K': + pos->perm_castling &= ~WKING; + break; + case 'k': + pos->perm_castling &= ~BKING; + break; + case 'Q': + pos->perm_castling &= ~WQUEEN; + break; + case 'q': + pos->perm_castling &= ~BQUEEN; + break; + } + } + + // Figure out en passant + char *enpassant = strtok_r(NULL, space, &saveptr1); + switch(enpassant[0]) + { + case '-': + pos->ep = EP_NONE; + break; + default: + pos->ep = enpassant[0] - 'a'; + break; + } + + // Figure out halfmove clock + char *halfmove = strtok_r(NULL, space, &saveptr1); + int half_move_clock = atoi(halfmove); + pos->half_move_clock = (signed char) half_move_clock; + + // Figure out fullmove number + char *fullmove = strtok_r(NULL, space, &saveptr1); + int fullmoves = atoi(fullmove); + pos->move_num = (uint16_t) (2 * fullmoves + pos->tomove); + + // Compute and impute the rest of the position + pos->wpieces = + pos->wrooks | pos->wknights | pos->wbishops | pos->wqueens | pos->wking | pos->wpawns; + pos->bpieces = + pos->brooks | pos->bknights | pos->bbishops | pos->bqueens | pos->bking | pos->bpawns; + pos->allpieces = pos->wpieces | pos->bpieces; + + pos->limp1 = pos->move_num; // don't know the limp1, so just set it to this move. + + pos->hash = make_hash(pos); + + assert(consistency(pos)); +} diff --git a/src/frontend.c b/src/frontend.c index 1e422bc..063b0a1 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -1,10 +1,12 @@ // frontend.c // functions for interacting with the user -#include "move.h" #include #include +#include "move.h" +#include "fenio.c" + // set the castling in mv void user_castling(struct position *pos, struct move *mv) { @@ -142,11 +144,14 @@ void user_move(struct position *pos) *newline = '\0'; FILE *fp = fopen(buffer, "r"); - if (fread(pos, sizeof(struct position), 1, fp) - == 0) { - fprintf(stderr, "Failed fread\n"); + char *fen = NULL; + size_t n; + if (getline(&fen, &n, fp) == -1) { + fprintf(stderr, "Failed getline\n"); } fclose(fp); + fen2pos(pos, fen); + free(fen); fprintf(stdout, "Resuming position from %s...\n",