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:
M | src/main.c | | | 36 | +++++++++++++++++++++++------------- |
M | src/pos.c | | | 45 | ++++++++++++++++++++++++++++++++++++++++----- |
M | src/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