shithub: moonfish

Download patch

ref: cdb1c9640d18a431b9bdac35c5e89c4ca6768ae0
parent: 522fcece1df230a6dd3b380cee723cbdf2c237ef
author: zamfofex <zamfofex@twdb.moe>
date: Wed Apr 17 15:54:18 EDT 2024

add underpromotions

--- a/README.md
+++ b/README.md
@@ -31,10 +31,9 @@
 
 These are things that might be fixed eventually.
 
-- the bot will never underpromote
-- the TUI will also prevent you from underpromoting
+- the TUIs do not let you underpromote
 - no transposition table
-- no support for `go infinite` or `go mate`
+- no support for `go infinite`, `go mate`, or `go nodes`
 - no move name or FEN validation (may lead to potential exploits)
 
 download
--- a/chess.c
+++ b/chess.c
@@ -62,7 +62,7 @@
 	-23, -8, 30, 0,
 };
 
-static void moonfish_create_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to)
+void moonfish_force_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to)
 {
 	move->from = from;
 	move->to = to;
@@ -74,20 +74,26 @@
 	move->passing = chess->passing;
 }
 
-void moonfish_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to)
+static void moonfish_pawn_moves(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to)
 {
-	moonfish_create_move(chess, move, from, to);
-	if (chess->board[from] % 16 == moonfish_pawn)
-	{
-		if (chess->board[from] / 16 == 1)
-		{
-			if (from > 80) move->promotion = moonfish_white_queen;
-		}
-		else
-		{
-			if (from < 40) move->promotion = moonfish_black_queen;
-		}
-	}
+	unsigned char color;
+	
+	moonfish_force_move(chess, (*moves)++, from, to);
+	if (chess->board[from] % 16 != moonfish_pawn) return;
+	
+	color = chess->board[from] & 0xF0;
+	if (color == 0x10 && from < 80) return;
+	if (color == 0x20 && from > 40) return;
+	
+	(*moves)--;
+	(*moves)[1] = **moves;
+	(*moves)[2] = **moves;
+	(*moves)[3] = **moves;
+	
+	(*moves)++->promotion = moonfish_queen | color;
+	(*moves)++->promotion = moonfish_rook | color;
+	(*moves)++->promotion = moonfish_bishop | color;
+	(*moves)++->promotion = moonfish_knight | color;
 }
 
 static void moonfish_jump(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, signed char delta)
@@ -96,7 +102,7 @@
 	to = from + delta;
 	if (chess->board[to] == moonfish_outside) return;
 	if (chess->board[to] / 16 == chess->board[from] / 16) return;
-	moonfish_create_move(chess, (*moves)++, from, to);
+	moonfish_force_move(chess, (*moves)++, from, to);
 }
 
 static void moonfish_slide(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, signed char delta)
@@ -109,7 +115,7 @@
 		to += delta;
 		if (chess->board[to] == moonfish_outside) break;
 		if (chess->board[to] / 16 == chess->board[from] / 16) break;
-		moonfish_create_move(chess, (*moves)++, from, to);
+		moonfish_force_move(chess, (*moves)++, from, to);
 		if (chess->board[to] != moonfish_empty) break;
 	}
 }
@@ -223,7 +229,7 @@
 {
 	if (to == chess->passing)
 	{
-		moonfish_create_move(chess, (*moves)++, from, to);
+		moonfish_force_move(chess, (*moves)++, from, to);
 		return;
 	}
 	
@@ -230,7 +236,7 @@
 	if (chess->board[to] / 16 != chess->board[from] / 16)
 	if (chess->board[to] != moonfish_empty)
 	if (chess->board[to] != moonfish_outside)
-		moonfish_move(chess, (*moves)++, from, to);
+		moonfish_pawn_moves(chess, moves, from, to);
 }
 
 static void moonfish_move_pawn(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
@@ -241,11 +247,11 @@
 	
 	if (chess->board[from + dy] == moonfish_empty)
 	{
-		moonfish_move(chess, (*moves)++, from, from + dy);
+		moonfish_pawn_moves(chess, moves, from, from + dy);
 				
 		if (chess->white ? from < 40 : from > 80)
 		if (chess->board[from + dy * 2] == moonfish_empty)
-			moonfish_move(chess, (*moves)++, from, from + dy * 2);
+			moonfish_pawn_moves(chess, moves, from, from + dy * 2);
 	}
 	
 	moonfish_pawn_capture(chess, moves, from, from + dy + 1);
@@ -454,7 +460,7 @@
 
 static void moonfish_from_xy(struct moonfish_chess *chess, struct moonfish_move *move, int x0, int y0, int x1, int y1)
 {
-	moonfish_create_move(chess, move, (x0 + 1) + (y0 + 2) * 10, (x1 + 1) + (y1 + 2) * 10);
+	moonfish_force_move(chess, move, (x0 + 1) + (y0 + 2) * 10, (x1 + 1) + (y1 + 2) * 10);
 }
 
 void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name)
@@ -558,6 +564,33 @@
 #ifndef moonfish_mini
 
 #include <string.h>
+
+int moonfish_move(struct moonfish_chess *chess, struct moonfish_move *found, unsigned char from, unsigned char to)
+{
+	struct moonfish_move moves[32];
+	struct moonfish_move *move;
+	int valid;
+	
+	moonfish_moves(chess, moves, from);
+	
+	for (move = moves ; move->piece != moonfish_outside ; move++)
+	{
+		if (move->to == to)
+		{
+			moonfish_play(chess, move);
+			valid = moonfish_validate(chess);
+			moonfish_unplay(chess, move);
+			
+			if (valid)
+			{
+				*found = *move;
+				return 0;
+			}
+		}
+	}
+	
+	return 1;
+}
 
 int moonfish_fen(struct moonfish_chess *chess, char *fen)
 {
--- a/moonfish.h
+++ b/moonfish.h
@@ -65,6 +65,7 @@
 void moonfish_chess(struct moonfish_chess *chess);
 
 void moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from);
+void moonfish_force_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to);
 
 void moonfish_play(struct moonfish_chess *chess, struct moonfish_move *move);
 void moonfish_unplay(struct moonfish_chess *chess, struct moonfish_move *move);
@@ -77,7 +78,6 @@
 void moonfish_new(struct moonfish_analysis *analysis, struct moonfish_chess *chess);
 void moonfish_free(struct moonfish_analysis *analysis);
 
-void moonfish_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to);
 void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
 void moonfish_to_uci(char *name, struct moonfish_move *move);
 
@@ -91,6 +91,7 @@
 int moonfish_from_san(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
 void moonfish_to_san(struct moonfish_chess *chess, char *name, struct moonfish_move *move);
 void moonfish_to_fen(struct moonfish_chess *chess, char *fen);
+int moonfish_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to);
 
 int moonfish_finished(struct moonfish_chess *chess);
 int moonfish_checkmate(struct moonfish_chess *chess);
--- a/search.c
+++ b/search.c
@@ -52,6 +52,7 @@
 	int visits;
 	unsigned char from, to;
 	unsigned char count;
+	unsigned char promotion;
 };
 
 struct moonfish_info
@@ -147,6 +148,7 @@
 			
 			node->children[node->count].from = move->from;
 			node->children[node->count].to = move->to;
+			node->children[node->count].promotion = move->promotion;
 			node->children[node->count].count = 0;
 			node->children[node->count].visits = 0;
 			node->count++;
@@ -187,7 +189,8 @@
 	
 	for (j = 0 ; j < node->count ; j++)
 	{
-		moonfish_move(&info->chess, &move, node->children[j].from, node->children[j].to);
+		moonfish_force_move(&info->chess, &move, node->children[j].from, node->children[j].to);
+		move.promotion = node->children[j].promotion;
 		
 		if (move.captured % 16 == moonfish_king)
 		{
@@ -267,7 +270,9 @@
 	{
 		analysis->info[j].chess = analysis->chess;
 		
-		moonfish_move(&analysis->info[j].chess, &move, analysis->root.children[i].from, analysis->root.children[i].to);
+		moonfish_force_move(&analysis->info[j].chess, &move, analysis->root.children[i].from, analysis->root.children[i].to);
+		move.promotion = analysis->root.children[i].promotion;
+		
 		moonfish_play(&analysis->info[j].chess, &move);
 		
 		if (!moonfish_validate(&analysis->chess)) continue;
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -499,32 +499,9 @@
 
 static int moonfish_move_from(struct moonfish_chess *chess, struct moonfish_move *found, int x0, int y0, int x1, int y1)
 {
-	struct moonfish_move moves[32];
-	struct moonfish_move *move;
-	int valid;
-	
 	y0 = 10 - y0;
 	y1 = 10 - y1;
-	
-	moonfish_moves(chess, moves, x0 + y0 * 10);
-	
-	for (move = moves ; move->piece != moonfish_outside ; move++)
-	{
-		if (move->to == x1 + y1 * 10)
-		{
-			moonfish_play(chess, move);
-			valid = moonfish_validate(chess);
-			moonfish_unplay(chess, move);
-			
-			if (valid)
-			{
-				*found = *move;
-				return 0;
-			}
-		}
-	}
-	
-	return 1;
+	return moonfish_move(chess, found, x0 + y0 * 10, x1 + y1 * 10);
 }
 
 static void moonfish_analyse(struct moonfish_fancy *fancy)
--- a/tools/play.c
+++ b/tools/play.c
@@ -183,12 +183,8 @@
 	exit(1);
 }
 
-static int moonfish_move_from(struct moonfish_chess *chess, struct moonfish_move *found, int x0, int y0, int x1, int y1)
+static int moonfish_move_from(struct moonfish_chess *chess, struct moonfish_move *move, int x0, int y0, int x1, int y1)
 {
-	struct moonfish_move moves[32];
-	struct moonfish_move *move;
-	int valid;
-	
 	if (!chess->white)
 	{
 		x0 = 9 - x0; y0 = 9 - y0;
@@ -198,25 +194,7 @@
 	y0 = 10 - y0;
 	y1 = 10 - y1;
 	
-	moonfish_moves(chess, moves, x0 + y0 * 10);
-	
-	for (move = moves ; move->piece != moonfish_outside ; move++)
-	{
-		if (move->to == x1 + y1 * 10)
-		{
-			moonfish_play(chess, move);
-			valid = moonfish_validate(chess);
-			moonfish_unplay(chess, move);
-			
-			if (valid)
-			{
-				*found = *move;
-				return 0;
-			}
-		}
-	}
-	
-	return 1;
+	return moonfish_move(chess, move, x0 + y0 * 10, x1 + y1 * 10);
 }
 
 static void moonfish_reset_time(struct moonfish_fancy *fancy)
--