commit b6f7fbad7dea4cf71ad7d8b00d6842b63f38bfd0
parent 87e142b2ea66019107aa1f58db1aac2142c7ee44
Author: benjamin paul <bpaul@bpaul.xyz>
Date: Sat, 23 Oct 2021 21:17:47 +1000
Added most of the parsefen function, excluding the fifty-move rule and the turn count
Diffstat:
3 files changed, 94 insertions(+), 20 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,7 +5,7 @@ NAME = bpaul-chess
CC = cc
CFLAGS = -march=native -O3 -flto
-OBJS = src/main.o src/bb.o src/gen.c
+OBJS = src/main.o src/bb.o src/gen.o src/pos.o
all: $(NAME)
diff --git a/src/pos.c b/src/pos.c
@@ -1,3 +1,6 @@
+#include <assert.h>
+#include <stdbool.h>
+
#include "bb.h"
#include "pos.h"
@@ -11,10 +14,15 @@ piece(unsigned char p) {
return p & 7;
}
+unsigned char
+square(unsigned char r, unsigned char c) {
+ return r*8 + c;
+}
+
void
-setpiece(pos *p, unsigned char piece, unsigned char sq) {
- setbit(p->sides[side(piece)], sq);
- setbit(p->pieces[piece(piece)], sq);
+setpiece(pos *p, unsigned char pc, unsigned char sq) {
+ setbit(&p->sides[side(pc)], sq);
+ setbit(&p->pieces[piece(pc)], sq);
}
void
@@ -22,24 +30,27 @@ parsefen(pos *p, char *fen) {
char phase, sq;
phase = 0;
- sq = 63;
+ sq = 56;
while (*fen) {
+ /* Piece placement */
if (phase == 0) {
switch (*fen) {
- case 'P': setpiece(p, wP, sq); break;
- case 'N': setpiece(p, wN, sq); break;
- case 'B': setpiece(p, wB, sq); break;
- case 'R': setpiece(p, wR, sq); break;
- case 'Q': setpiece(p, wQ, sq); break;
- case 'K': setpiece(p, wK, sq); break;
- case 'p': setpiece(p, bP, sq); break;
- case 'n': setpiece(p, bN, sq); break;
- case 'b': setpiece(p, bB, sq); break;
- case 'r': setpiece(p, bR, sq); break;
- case 'q': setpiece(p, bQ, sq); break;
- case 'k': setpiece(p, bK, sq); break;
+ /* Place a piece on the current square */
+ case 'P': setpiece(p, wP, sq); sq++; break;
+ case 'N': setpiece(p, wN, sq); sq++; break;
+ case 'B': setpiece(p, wB, sq); sq++; break;
+ case 'R': setpiece(p, wR, sq); sq++; break;
+ case 'Q': setpiece(p, wQ, sq); sq++; break;
+ case 'K': setpiece(p, wK, sq); sq++; break;
+ case 'p': setpiece(p, bP, sq); sq++; break;
+ case 'n': setpiece(p, bN, sq); sq++; break;
+ case 'b': setpiece(p, bB, sq); sq++; break;
+ case 'r': setpiece(p, bR, sq); sq++; break;
+ case 'q': setpiece(p, bQ, sq); sq++; break;
+ case 'k': setpiece(p, bK, sq); sq++; break;
+ /* Move over to the rightby the number specified */
case '1':
case '2':
case '3':
@@ -48,13 +59,76 @@ parsefen(pos *p, char *fen) {
case '6':
case '7':
case '8':
- sq -= *fen - '0';
+ /* In case you were unaware, subtracting '0' from an ascii
+ * character which is a number gives the integer value of
+ * the number. For example, '8' - '0' = 8. */
+ sq += *fen - '0';
case '/':
- sq = (sq & ~7) - 1;
+ /* This should only occur after we have moved past the last
+ * column in the current row. We will be placed in the
+ * first column of the row above the current one, but we
+ * would want to be in the row below us, so we get shifted
+ * by 2 rows downwards. */
+ assert(sq % 8 == 0);
+ sq -= 16;
+
+ default:
+ /* There was an error in the fen */
+ assert(0);
+ }
+
+ if (sq < 0) { phase++; fen += 2; }
+ }
+
+ /* Turn */
+ if (phase == 1) {
+ fen++;
+ if (*fen == 'w') {
+ p->turn = WHITE;
+ } else {
+ p->turn = BLACK;
+ }
+ phase++;
+ fen += 2;
+ }
+
+ /* Castling rights */
+ if (phase == 2 && *fen != ' ') {
+ switch (*fen) {
+ /* The castling rights value is a bitset, i.e. each of the
+ * first four bits represent a different castling right. */
+ case 'K': p->castle |= 8; break;
+ case 'Q': p->castle |= 4; break;
+ case 'k': p->castle |= 2; break;
+ case 'q': p->castle |= 1; break;
+
+ /* If it is not one of these characters there is
+ * something wrong with the fen */
+ default: assert(0);
}
+ } else if (phase == 2) phase++;
+
+ /* En passant */
+ if (phase == 3) {
+ fen++;
+ /* Extract the column and row */
+ char c = *fen - 'a';
+ fen++;
+ char r = *fen - '1';
+ /* Calculate the square based on the column and row */
+ p->enpas = square(r, c);
+ fen+=2;
}
+ /* I cant be bothered to do the rest right now */
+
+
+
+ /* Fifty-move rule */
+
+ /* Turn count */
+
fen++;
}
}
diff --git a/src/pos.h b/src/pos.h
@@ -22,4 +22,4 @@ struct pos {
char turn;
};
-void parsefen(pos *, char);
+void parsefen(pos *, char *);