ref: 0a01d63f476aa04ecbfd563044288b3d605f6456
parent: 9235e718b5bca7692fea883a24daa21867c61fcd
author: zamfofex <zamfofex@twdb.moe>
date: Mon Oct 16 13:50:05 EDT 2023
add WDL support, SAN, and annotations to ‘analyse’ + bug fixes
--- a/chess.c
+++ b/chess.c
@@ -241,6 +241,11 @@
chess->board[move->from] = moonfish_empty;
chess->board[move->to] = move->promotion;
+ if (move->piece == moonfish_our_pawn)
+ if ((move->to - move->from) % 10)
+ if (move->captured == moonfish_empty)
+ chess->board[move->to - 10] = moonfish_empty;
+
if (move->piece == moonfish_our_king)
{x0 = 0;
@@ -325,9 +330,8 @@
moonfish_fen(chess, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq");
}
-void moonfish_play_uci(struct moonfish_chess *chess, char *name)
+void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name)
{- struct moonfish_move move;
int x, y;
x = name[0] - 'a';
@@ -339,7 +343,7 @@
y = 7 - y;
}
- move.from = (x + 1) + (y + 2) * 10;
+ move->from = (x + 1) + (y + 2) * 10;
x = name[2] - 'a';
y = name[3] - '1';
@@ -350,23 +354,16 @@
y = 7 - y;
}
- move.to = (x + 1) + (y + 2) * 10;
+ move->to = (x + 1) + (y + 2) * 10;
- move.piece = chess->board[move.from];
- move.captured = chess->board[move.to];
- move.promotion = move.piece;
+ move->piece = chess->board[move->from];
+ move->captured = chess->board[move->to];
+ move->promotion = move->piece;
- if (move.piece == moonfish_our_pawn)
- if ((move.to - move.from) % 10)
- if (move.captured == moonfish_empty)
- chess->board[move.to - 10] = moonfish_empty;
-
- if (name[4] == 'q') move.promotion = moonfish_our_queen;
- if (name[4] == 'r') move.promotion = moonfish_our_rook;
- if (name[4] == 'b') move.promotion = moonfish_our_bishop;
- if (name[4] == 'n') move.promotion = moonfish_our_knight;
-
- moonfish_play(chess, &move);
+ if (name[4] == 'q') move->promotion = moonfish_our_queen;
+ if (name[4] == 'r') move->promotion = moonfish_our_rook;
+ if (name[4] == 'b') move->promotion = moonfish_our_bishop;
+ if (name[4] == 'n') move->promotion = moonfish_our_knight;
}
void moonfish_to_uci(char *name, struct moonfish_move *move, int white)
--- a/main.c
+++ b/main.c
@@ -167,7 +167,10 @@
if (arg != NULL && !strcmp(arg, "moves"))
{while ((arg = strtok(NULL, "\r\n\t ")) != NULL)
- moonfish_play_uci(&ctx->chess, arg);
+ {+ moonfish_from_uci(&ctx->chess, &move, arg);
+ moonfish_play(&ctx->chess, &move);
+ }
}
}
else if (!strcmp(arg, "uci"))
--- a/moonfish.h
+++ b/moonfish.h
@@ -80,7 +80,7 @@
int moonfish_best_move(struct moonfish *ctx, struct moonfish_move *move, int time);
-void moonfish_play_uci(struct moonfish_chess *chess, char *name);
+void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
void moonfish_to_uci(char *name, struct moonfish_move *move, int white);
int moonfish_validate(struct moonfish_chess *chess);
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -13,7 +13,7 @@
{struct moonfish_chess chess;
char name[6];
- char san[12];
+ char san[16];
int white, black, draw;
int score;
int checkmate;
@@ -168,14 +168,49 @@
static void moonfish_scoresheet_move(struct moonfish_fancy *fancy, int i)
{+ struct moonfish_ply *ply;
+ int checkmate;
+ int score;
+
+ ply = fancy->plies + i;
+
if (i >= fancy->count)
{- printf("%11s", "");+ printf("%10s", "");return;
}
+
if (i == fancy->i) printf("\x1B[48;5;248m\x1B[38;5;235m");- printf(" %-7s ", fancy->plies[i].san);- if (i == fancy->i) printf("\x1B[0m");+ printf(" %s", ply->san);+
+ if (ply->checkmate)
+ {+ checkmate = ply->checkmate;
+ if (checkmate < 0) checkmate *= -1;
+
+ printf("\x1B[38;5;162m#");+
+ if (ply->checkmate > 0) printf("+");+ else printf("-");+
+ if (checkmate < 10)
+ printf("%d", checkmate);+ else
+ printf("X");+ }
+ else if (i > 0)
+ {+ score = ply->score + fancy->plies[i - 1].score;
+ if (fancy->plies[i - 1].checkmate || score > 200) printf("\x1B[38;5;124m?? ");+ else if (score > 100) printf("\x1B[38;5;173m? ");+ else printf(" ");+ }
+ else
+ {+ printf(" ");+ }
+
+ printf("%*s\x1B[0m", 6 - (int) strlen(ply->san), "");}
static void moonfish_scoresheet(struct moonfish_fancy *fancy)
@@ -243,23 +278,117 @@
moonfish_evaluation(fancy);
printf("\x1B[%d;24H", fancy->oy + 7);- printf("best:%s\n", fancy->pv);+ printf("best:%s%32s\n", fancy->pv, "");fflush(stdout);
}
+static void moonfish_to_san(struct moonfish_chess *chess, char *name, struct moonfish_move *move)
+{+ static char names[] = "NBRQK";
+
+ int x, y;
+ struct moonfish_move moves[32];
+ struct moonfish_move *other_move;
+ char file_ambiguity, rank_ambiguity, ambiguity;
+ int to_x, to_y;
+ int from_x, from_y;
+
+ from_x = move->from % 10 - 1;
+ from_y = move->from / 10 - 2;
+
+ to_x = move->to % 10 - 1;
+ to_y = move->to / 10 - 2;
+
+ if (!chess->white)
+ {+ from_x = 7 - from_x;
+ from_y = 7 - from_y;
+ to_x = 7 - to_x;
+ to_y = 7 - to_y;
+ }
+
+ if (move->piece == moonfish_our_pawn)
+ {+ if (from_x != to_x)
+ {+ *name++ = from_x + 'a';
+ *name++ = 'x';
+ }
+
+ *name++ = to_x + 'a';
+ *name++ = to_y + '1';
+
+ if (move->promotion != moonfish_our_pawn)
+ {+ *name++ = '=';
+ *name++ = names[(move->promotion & 0xF) - 2];
+ }
+
+ *name = 0;
+
+ return;
+ }
+
+ file_ambiguity = 0;
+ rank_ambiguity = 0;
+ ambiguity = 0;
+
+ for (y = 0 ; y < 8 ; y++)
+ for (x = 0 ; x < 8 ; x++)
+ {+ if ((x + 1) + (y + 2) * 10 == move->from) continue;
+ moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+
+ for (other_move = moves ; other_move->piece != moonfish_outside ; other_move++)
+ {+ if (other_move->to != move->to) continue;
+ if (other_move->piece != move->piece) continue;
+
+ ambiguity = 1;
+ if (other_move->from % 10 - 1 == from_x) file_ambiguity = 1;
+ if (other_move->from / 10 - 2 == from_y) rank_ambiguity = 1;
+ }
+ }
+
+ *name++ = names[(move->piece & 0xF) - 2];
+
+ if (ambiguity)
+ {+ if (file_ambiguity)
+ {+ if (rank_ambiguity)
+ *name++ = from_x + 'a';
+ *name++ = from_y + '1';
+ }
+ else
+ {+ *name++ = from_x + 'a';
+ }
+ }
+
+ if (move->captured != moonfish_empty)
+ *name++ = 'x';
+
+ *name++ = to_x + 'a';
+ *name++ = to_y + '1';
+
+ *name = 0;
+}
+
static void *moonfish_start(void *data)
{static char line[2048];
+ static struct moonfish_ply ply;
+ static char san[16];
struct moonfish_fancy *fancy;
char *arg;
int score;
char *buffer;
- struct moonfish_ply *ply;
- int depth;
struct pollfd fds;
unsigned int i, length;
+ struct moonfish_move move;
fancy = data;
@@ -293,8 +422,8 @@
arg = strtok_r(line, "\r\n\t ", &buffer);
if (arg == NULL) continue;
- ply = fancy->plies + fancy->i;
- depth = 0;
+ ply = fancy->plies[fancy->i];
+ ply.depth = 0;
for (;;)
{@@ -301,10 +430,13 @@
arg = strtok_r(NULL, "\r\n\t ", &buffer);
if (arg == NULL) break;
+ if (!strcmp(arg, "lowerbound")) break;
+ if (!strcmp(arg, "upperbound")) break;
+
if (!strcmp(arg, "depth"))
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
- if (arg == NULL || sscanf(arg, "%d", &depth) != 1)
+ if (arg == NULL || sscanf(arg, "%d", &ply.depth) != 1)
{fprintf(stderr, "%s: malformed 'depth' in 'info' command\n", fancy->argv0);
exit(1);
@@ -320,18 +452,59 @@
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
if (arg == NULL) break;
- length = strlen(arg);
+ moonfish_from_uci(&ply.chess, &move, arg);
+ moonfish_to_san(&ply.chess, san, &move);
+ length = strlen(san);
if (i + length > sizeof fancy->pv - 2) break;
+ moonfish_play(&ply.chess, &move);
fancy->pv[i++] = ' ';
- strcpy(fancy->pv + i, arg);
+ strcpy(fancy->pv + i, san);
i += length;
}
- fancy->pv[i] = 0;
+ fancy->plies[fancy->i].score = ply.score;
+ fancy->plies[fancy->i].white = ply.white;
+ fancy->plies[fancy->i].black = ply.black;
+ fancy->plies[fancy->i].draw = ply.draw;
+ fancy->plies[fancy->i].checkmate = ply.checkmate;
+ fancy->plies[fancy->i].depth = ply.depth;
break;
}
+ if (!strcmp(arg, "wdl"))
+ {+ arg = strtok_r(NULL, "\r\n\t ", &buffer);
+ if (arg == NULL || sscanf(arg, "%d", &ply.white) != 1)
+ {+ fprintf(stderr, "%s: malformed 'wdl' win in 'info' command\n", fancy->argv0);
+ exit(1);
+ }
+ arg = strtok_r(NULL, "\r\n\t ", &buffer);
+ if (arg == NULL || sscanf(arg, "%d", &ply.draw) != 1)
+ {+ fprintf(stderr, "%s: malformed 'wdl' draw in 'info' command\n", fancy->argv0);
+ exit(1);
+ }
+ arg = strtok_r(NULL, "\r\n\t ", &buffer);
+ if (arg == NULL || sscanf(arg, "%d", &ply.black) != 1)
+ {+ fprintf(stderr, "%s: malformed 'wdl' loss in 'info' command\n", fancy->argv0);
+ exit(1);
+ }
+
+ ply.checkmate = 0;
+
+ if (!ply.chess.white)
+ {+ score = ply.white;
+ ply.white = ply.black;
+ ply.black = score;
+ }
+
+ continue;
+ }
+
if (strcmp(arg, "score")) continue;
arg = strtok_r(NULL, "\r\n\t ", &buffer);
@@ -346,21 +519,20 @@
exit(1);
}
- ply->score = score;
- ply->white = 100;
- ply->black = 100;
- ply->depth = depth;
- ply->draw = 0;
- ply->checkmate = 0;
+ ply.score = score;
+ ply.white = 100;
+ ply.black = 100;
+ ply.draw = 0;
+ ply.checkmate = 0;
- if (score > 0) ply->white += score;
- else ply->black -= score;
+ if (score > 0) ply.white += score;
+ else ply.black -= score;
- if (!ply->chess.white)
+ if (!ply.chess.white)
{- score = ply->white;
- ply->white = ply->black;
- ply->black = score;
+ score = ply.white;
+ ply.white = ply.black;
+ ply.black = score;
}
continue;
@@ -375,14 +547,13 @@
exit(1);
}
- if (!ply->chess.white) score *= -1;
+ if (!ply.chess.white) score *= -1;
- ply->white = 0;
- ply->black = 0;
- ply->draw = 0;
- ply->checkmate = score;
- ply->score = 0;
- ply->depth = depth;
+ ply.white = 0;
+ ply.black = 0;
+ ply.draw = 0;
+ ply.checkmate = score;
+ ply.score = 0;
continue;
}
@@ -751,9 +922,10 @@
fancy->count = fancy->i + 1;
fancy->plies[fancy->i] = fancy->plies[fancy->i - 1];
fancy->plies[fancy->i].depth = 0;
+ fancy->plies[fancy->i].score *= -1;
moonfish_to_uci(fancy->plies[fancy->i].name, &move, fancy->plies[fancy->i].chess.white);
- strcpy(fancy->plies[fancy->i].san, fancy->plies[fancy->i].name);
+ moonfish_to_san(&fancy->plies[fancy->i].chess, fancy->plies[fancy->i].san, &move);
moonfish_play(&fancy->plies[fancy->i].chess, &move);
fancy->x = 0;
--- a/tools/play.c
+++ b/tools/play.c
@@ -264,6 +264,7 @@
{int white_time, black_time;
char *arg;
+ struct moonfish_move move;
if (fancy->white == fancy->chess.white)
{@@ -295,7 +296,8 @@
strcpy(name, arg);
pthread_mutex_lock(fancy->mutex);
- moonfish_play_uci(&fancy->chess, arg);
+ moonfish_from_uci(&fancy->chess, &move, arg);
+ moonfish_play(&fancy->chess, &move);
}
int main(int argc, char **argv)
--- a/tools/utils.c
+++ b/tools/utils.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <fcntl.h>
#include "tools.h"
@@ -8,7 +9,7 @@
int moonfish_spawn(char *argv0, char **argv, int *in, int *out)
{int p1[2], p2[2];
- int pid;
+ int pid, fd;
if (pipe(p1) == -1) return 1;
if (pipe(p2) == -1) return 1;
@@ -25,8 +26,16 @@
return 0;
}
+ fd = open("/dev/null", O_RDONLY);+ if (fd < 0)
+ {+ fprintf(stderr, "%s: %s: %s\n", argv0, argv[0], strerror(errno));
+ exit(1);
+ }
+
dup2(p1[0], 0);
dup2(p2[1], 1);
+ dup2(p2[1], 2);
close(p1[0]);
close(p1[1]);
--
⑨