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)
--
⑨