shithub: moonfish

Download patch

ref: 2f1cfd92ec6e726b72d2a955d5ba69c9dc4991a2
parent: 4b398de822885a43bbb6d95b4c6a8fb2ce1992dc
author: zamfofex <zamfofex@twdb.moe>
date: Fri Jun 20 15:49:40 EDT 2025

make position validation faster

--- a/chess.c
+++ b/chess.c
@@ -38,21 +38,53 @@
 
 int moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, int from);
 
-int moonfish_validate(struct moonfish_chess *chess)
+static int moonfish_deltas1(struct moonfish_chess *chess, int piece, int from, int *deltas, int count, int n)
 {
-	int x, y;
-	struct moonfish_move moves[32];
-	int i, count;
+	int i;
+	int to;
 	
-	for (y = 0 ; y < 8 ; y++) {
-		for (x = 0 ; x < 8 ; x++) {
-			count = moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
-			for (i = 0 ; i < count ; i++) {
-				if (chess->board[moves[i].to] % 16 == moonfish_king) return 0;
-			}
+	while (*deltas) {
+		to = from;
+		for (i = 0 ; i < count ; i++) {
+			to += *deltas * n;
+			if (chess->board[to] == moonfish_outside) break;
+			if (chess->board[to] == piece) return 1;
+			if (chess->board[to] != moonfish_empty) break;
 		}
+		deltas++;
 	}
 	
+	return 0;
+}
+
+int moonfish_validate(struct moonfish_chess *chess)
+{
+	static int steps[] = {0, 1, 8, 8, 8, 1};
+	static int deltas[][5] = {
+		{0},
+		{21, 19, 12, 8, 0},
+		{11, 9, 0},
+		{10, 1, 0},
+		{10, 1, 11, 9, 0},
+		{10, 1, 11, 9, 0},
+	};
+	
+	int type, color;
+	int i, dy;
+	
+	i = chess->king_indices[chess->white];
+	
+	color = chess->white ? 0x10 : 0x20;
+	dy = chess->white ? -10 : 10;
+	
+	for (type = 2 ; type <= 6 ; type++) {
+		if (moonfish_deltas1(chess, color | type, i, deltas[type - 1], steps[type - 1], 1)) return 0;
+		if (moonfish_deltas1(chess, color | type, i, deltas[type - 1], steps[type - 1], -1)) return 0;
+	}
+	
+	if (chess->board[i + dy - 1] == (color | moonfish_pawn)) return 0;
+	if (chess->board[i + dy + 1] == (color | moonfish_pawn)) return 0;
+	
 	return 1;
 }
 
@@ -76,6 +108,7 @@
 	other = *chess;
 	other.board[from] = moonfish_empty;
 	other.board[to] = chess->white ? moonfish_white_king : moonfish_black_king;
+	other.king_indices[chess->white ^ 1] = to;
 	return moonfish_check(&other);
 }
 
@@ -188,6 +221,7 @@
 	if (move->piece % 16 == moonfish_king) {
 		chess->oo[chess->white ^ 1] = 0;
 		chess->ooo[chess->white ^ 1] = 0;
+		chess->king_indices[chess->white ^ 1] = move->to;
 		if (move->to - move->from == 2) {
 			chess->board[move->to - 1] = chess->board[move->to + 1];
 			chess->board[move->to + 1] = moonfish_empty;
@@ -219,6 +253,8 @@
 	chess->ooo[0] = 1;
 	chess->ooo[1] = 1;
 	chess->passing = 0;
+	chess->king_indices[0] = 25;
+	chess->king_indices[1] = 95;
 	
 	for (x = 0 ; x < 120 ; x++) chess->board[x] = moonfish_outside;
 	
@@ -438,6 +474,7 @@
 		
 		if (x >= 8 || y >= 8) return 1;
 		chess->board[(x + 1) + (9 - y) * 10] = type | color;
+		if (type == moonfish_king) chess->king_indices[color / 16 - 1] = (x + 1) + (9 - y) * 10;
 		
 		x++;
 	}
--- a/moonfish.h
+++ b/moonfish.h
@@ -72,6 +72,9 @@
 	/* flags representing castling rights */
 	unsigned char oo[2], ooo[2];
 	
+	/* indices of each king on the board */
+	unsigned char king_indices[2];
+	
 	/* square index of a pawn that may be captured via e.p. */
 	/* or zero if there is no such pawn */
 	unsigned char passing;
--