shithub: moonfish

Download patch

ref: d651ab6474d4380fb93500bb9e5ee681b51ac21f
parent: c8a9c80b8171efcd0db5f54e899d30057eead191
author: zamfofex <zamfofex@twdb.moe>
date: Mon Dec 18 08:00:33 EST 2023

better stalemate and checkmate detection

--- a/README.md
+++ b/README.md
@@ -31,7 +31,6 @@
   - no en passant
   - no underpromotion
 - the TUI will also prevent you from making those kinds of moves
-- the TUI does not detect when the game has ended due to stalemate or checkmate
 - no transposition table
 - no good move ordering heuristic
 - no support for `go infinite` or `go mate`
--- a/chess.c
+++ b/chess.c
@@ -589,3 +589,38 @@
 	
 	return valid ^ 1;
 }
+
+int moonfish_finished(struct moonfish_chess *chess)
+{
+	int x, y;
+	struct moonfish_move moves[32];
+	struct moonfish_move *move;
+	int valid;
+	
+	for (y = 0 ; y < 8 ; y++)
+	for (x = 0 ; x < 8 ; x++)
+	{
+		moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+		for (move = moves ; move->piece != moonfish_outside ; move++)
+		{
+			moonfish_play(chess, move);
+			valid = moonfish_validate(chess);
+			moonfish_unplay(chess, move);
+			if (valid) return 0;
+		}
+	}
+	
+	return 1;
+}
+
+int moonfish_checkmate(struct moonfish_chess *chess)
+{
+	if (!moonfish_finished(chess)) return 0;
+	return moonfish_check(chess);
+}
+
+int moonfish_stalemate(struct moonfish_chess *chess)
+{
+	if (!moonfish_finished(chess)) return 0;
+	return moonfish_check(chess) ^ 1;
+}
--- a/moonfish.h
+++ b/moonfish.h
@@ -79,5 +79,8 @@
 
 int moonfish_validate(struct moonfish_chess *chess);
 int moonfish_check(struct moonfish_chess *chess);
+int moonfish_checkmate(struct moonfish_chess *chess);
+int moonfish_stalemate(struct moonfish_chess *chess);
+int moonfish_finished(struct moonfish_chess *chess);
 
 #endif
--- a/search.c
+++ b/search.c
@@ -151,6 +151,24 @@
 		
 		moonfish_play(&ctx->chess, moves);
 		
+		if (moonfish_checkmate(&ctx->chess))
+		{
+			*best_move = *moves;
+			moonfish_unplay(&ctx->chess, moves);
+			return -200 * moonfish_omega;
+		}
+		
+		if (moonfish_stalemate(&ctx->chess))
+		{
+			if (best_score < 0)
+			{
+				*best_move = *moves;
+				best_score = 0;
+			}
+			moonfish_unplay(&ctx->chess, moves++);
+			continue;
+		}
+		
 		if (!moonfish_validate(&ctx->chess))
 		{
 			moonfish_unplay(&ctx->chess, moves++);
--- a/tools/play.c
+++ b/tools/play.c
@@ -572,6 +572,7 @@
 				moonfish_play(&fancy->chess, &move);
 				moonfish_reset_time(fancy);
 				moonfish_fancy(fancy);
+				if (moonfish_finished(&fancy->chess)) break;
 				
 				pthread_mutex_unlock(fancy->mutex);
 				
@@ -583,6 +584,8 @@
 				name += strlen(name);
 				moonfish_reset_time(fancy);
 				moonfish_fancy(fancy);
+				if (moonfish_finished(&fancy->chess)) break;
+				
 				pthread_mutex_unlock(fancy->mutex);
 				
 				printf("\x1B[?1000h");
--