bpaul-chess

UCI chess engine to replace Omelette Chess Engine
Log | Files | Refs | README | LICENSE

commit ed6793101504aebf59c0fcb98d1ea78466e154dd
parent 5a93117d3877330488326b0feea20e42e0bdba45
Author: benjamin paul <bpaul@bpaul.xyz>
Date:   Sat, 23 Oct 2021 22:20:46 +1000

Printing the board plus fix everything that was broken that was found in the process

Diffstat:
Msrc/main.c | 36+++++++++++++++++++++++-------------
Msrc/pos.c | 45++++++++++++++++++++++++++++++++++++++++-----
Msrc/pos.h | 33+++++++++++++++++++++++++++------
3 files changed, 90 insertions(+), 24 deletions(-)

diff --git a/src/main.c b/src/main.c @@ -2,6 +2,12 @@ #include <stdio.h> #include <string.h> +#include "bb.h" +#include "pos.h" + +#define BUFSIZE 8192 +#define START_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + #define VERSION "v0.0.1" /* sizeof magically gets the length of the string! (plus \0) */ @@ -9,21 +15,15 @@ int main() { - /* If your computer does not have enough RAM to support a 2KiB buffer, it - * probably wont be able to run the program. - * - * A 2048 character buffer may be too small for a position command, a - * setoption command or a go searchmoves command. The position command is - * the only command out of these which may be used in an actual setting. - * For it to be the case that the command is too big, there must be - * (2048-23)/5 moves made being the buffer size minus the length of - * "position startpos moves" divided by the size of a move, being 4 - * characters and a space. This means that with this buffer size, a game - * cannot go on for longer than 405 moves. */ - char buf[2048]; + char buf[BUFSIZE]; + + /* Create a position structure */ + pos p; + + parse_fen(&p, START_FEN); for (;;) { - fgets(buf, 2048, stdin); + fgets(buf, BUFSIZE, stdin); if (CMD("uci")) { puts("id name bpaul-chess " VERSION); @@ -33,7 +33,17 @@ main() { puts("readyok"); } else if (CMD("quit")) { break; + } else if (CMD("position startpos")) { + /* Still would need to do the moves section of this command :( */ + parse_fen(&p, START_FEN); + } else if (CMD("position fen")) { + parse_fen(&p, buf + 11); + } +#ifndef NDEBUG /* Debug commands! */ + else if (CMD("print")) { + print_board(&p); } +#endif } return 0; diff --git a/src/pos.c b/src/pos.c @@ -1,5 +1,6 @@ #include <assert.h> #include <stdbool.h> +#include <stdio.h> #include "bb.h" #include "pos.h" @@ -23,10 +24,26 @@ void setpiece(pos *p, unsigned char pc, unsigned char sq) { setbit(&p->sides[side(pc)], sq); setbit(&p->pieces[piece(pc)], sq); + p->mailbox[sq] = pc; } void -parsefen(pos *p, char *fen) { +reset_board(pos *p) { + int i; + for (i = 0; i < 2; i++) p->sides[i] = 0; + for (i = 0; i < 6; i++) p->pieces[i] = 0; + for (i = 0; i < 64; i++) p->mailbox[i] = nP; + p->castle = 0; + p->enpas = NO_SQ; + p->fifty = 0; + p->game_length = 0; + p->turn = WHITE; +} + +void +parse_fen(pos *p, char *fen) { + reset_board(p); + char phase, sq; phase = 0; @@ -63,6 +80,7 @@ parsefen(pos *p, char *fen) { * character which is a number gives the integer value of * the number. For example, '8' - '0' = 8. */ sq += *fen - '0'; + break; case '/': /* This should only occur after we have moved past the last @@ -72,13 +90,17 @@ parsefen(pos *p, char *fen) { * by 2 rows downwards. */ assert(sq % 8 == 0); sq -= 16; + break; + + case ' ': + phase = 1; + fen++; + break; default: /* There was an error in the fen */ - assert(0); + printf("Fen error, character %c, sq %d", *fen, sq); } - - if (sq < 0) { phase++; fen += 2; } } /* Turn */ @@ -105,7 +127,7 @@ parsefen(pos *p, char *fen) { /* If it is not one of these characters there is * something wrong with the fen */ - default: assert(0); + default: printf("Fen error"); } } else if (phase == 2) phase++; @@ -132,3 +154,16 @@ parsefen(pos *p, char *fen) { fen++; } } + +#ifndef NDEBUG +void +print_board(pos *p) { + int r,c; + for (r = 7; r >= 0; r--) { + for (c = 0; c <= 7; c++) { + putchar("pnbrqk PNBRQK."[p->mailbox[square(r,c)]]); + } + puts(""); + } +} +#endif diff --git a/src/pos.h b/src/pos.h @@ -1,19 +1,35 @@ #ifndef POS_H #define POS_H -enum { WHITE, BLACK, SIDE_CNT }; +enum { WHITE, BLACK }; -enum { PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, PIECE_CNT }; +enum { PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING }; /* Please format this better! */ enum { wP, wN, wB, wR, wQ, wK, - bP = 8, bN, bB, bR, bQ, bK }; + bP = 8, bN, bB, bR, bQ, bK, + nP /* No piece */ +}; + +/* Square names enum */ +enum { + A1, B1, C1, D1, E1, F1, G1, H1, + A2, B2, C2, D2, E2, F2, G2, H2, + A3, B3, C3, D3, E3, F3, G3, H3, + A4, B4, C4, D4, E4, F4, G4, H4, + A5, B5, C5, D5, E5, F5, G5, H5, + A6, B6, C6, D6, E6, F6, G6, H6, + A7, B7, C7, D7, E7, F7, G7, H7, + A8, B8, C8, D8, E8, F8, G8, H8, + NO_SQ +}; typedef struct pos pos; struct pos { - bb sides[SIDE_CNT]; - bb pieces[PIECE_CNT]; + bb sides[2]; + bb pieces[6]; + char mailbox[64]; /* Array of piece positions used for square lookup */ char castle; /* Castling permissions flags */ char enpas; /* En passant square */ unsigned char fifty; /* Tracker for 50 move rule */ @@ -21,5 +37,10 @@ struct pos { char turn; }; -void parsefen(pos *, char *); +void reset_board(pos *); +void parse_fen(pos *, char *); +#ifndef NDEBUG +void print_board(pos *); +#endif + #endif