ref: 63d3844e193a3ca13548c44f02f95822781ef1f0
parent: eedc1ae645866a6b09b2afe3c8329b24d2a68fcf
author: zamfofex <zamfofex@twdb.moe>
date: Mon Oct 7 14:21:19 EDT 2024
improvements to analysis TUI
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -15,6 +15,7 @@
{struct moonfish_chess chess;
char name[6];
+ char best[6];
char san[16];
int white, black, draw;
int score;
@@ -26,7 +27,7 @@
{struct moonfish_ply plies[256];
int i, count;
- pthread_mutex_t *mutex, *read_mutex;
+ pthread_mutex_t *mutex;
char *argv0;
int x, y;
FILE *in, *out;
@@ -34,7 +35,9 @@
int ox, oy;
int offset;
char pv[32];
- int time;
+ int time, taken;
+ int idle;
+ int stop;
};
static void moonfish_fancy_square(struct moonfish_fancy *fancy, int x, int y)
@@ -55,7 +58,7 @@
if (piece == moonfish_empty)
{ printf(" ");- return;
+ return;
}
if (piece >> 4 == 1)
@@ -182,8 +185,13 @@
if (i == fancy->i) printf("\x1B[48;5;248m\x1B[38;5;235m"); printf(" %s", ply->san);- if (ply->checkmate)
+ if (moonfish_finished(&ply->chess))
{+ if (moonfish_checkmate(&ply->chess)) printf("\x1B[38;5;160m# ");+ else printf("\x1B[38;5;111m(0)");+ }
+ else if (ply->checkmate)
+ {checkmate = ply->checkmate;
if (checkmate < 0) checkmate *= -1;
@@ -242,7 +250,9 @@
struct moonfish_ply *ply;
int score;
- printf("\x1B[38;5;111m(+)\x1B[0m ");+ if (fancy->idle == 0) printf("\x1B[38;5;103m");+ else printf("\x1B[38;5;111m");+ printf("(+)\x1B[0m ");ply = fancy->plies + fancy->i;
score = ply->score;
@@ -249,14 +259,21 @@
if (!ply->chess.white) score *= -1;
- if (ply->checkmate != 0)
+ if (moonfish_checkmate(&ply->chess))
+ printf("\x1B[38;5;160m#\x1B[0m");+ else if (moonfish_finished(&ply->chess))
+ printf("0");+ else if (ply->checkmate != 0)
printf("#%d", ply->checkmate);else if (score < 0)
- printf("-%d.%.2d", -score / 100, -score % 100);+ printf("-%d.%02d", -score / 100, -score % 100);else
- printf("%d.%.2d", score / 100, score % 100);+ printf("%d.%02d", score / 100, score % 100);- printf(" (depth %d) %4s", ply->depth, "");+ printf(" (depth %d)", ply->depth);+ if (fancy->idle == 0) printf(" in %d.%ds of %ds", fancy->taken / 1000, fancy->taken % 1000 / 100, fancy->time / 1000);+ else printf(" in %ds", fancy->time / 1000);+ printf(" %24s", "");}
static void moonfish_fancy(struct moonfish_fancy *fancy)
@@ -293,53 +310,45 @@
static char line[2048];
static struct moonfish_ply ply;
static char san[16];
+ static struct moonfish_move move;
struct moonfish_fancy *fancy;
char *arg;
int score;
char *buffer;
- struct pollfd fds;
unsigned int i, length;
- struct moonfish_move move;
+ int changed;
fancy = data;
- fds.fd = fileno(fancy->out);
- if (fds.fd < 0)
- {- perror(fancy->argv0);
- exit(1);
- }
-
- fds.events = POLLIN;
-
pthread_mutex_lock(fancy->mutex);
+ changed = 0;
+
for (;;)
{- moonfish_fancy(fancy);
- pthread_mutex_unlock(fancy->mutex);
+ if (changed != 0) moonfish_fancy(fancy);
+ changed = 0;
- pthread_mutex_lock(fancy->read_mutex);
- if (poll(&fds, 1, 250) == -1)
- {- perror(fancy->argv0);
- exit(1);
- }
- if ((fds.revents & POLLIN) == 0)
- {- pthread_mutex_unlock(fancy->read_mutex);
- pthread_mutex_lock(fancy->mutex);
- continue;
- }
+ pthread_mutex_unlock(fancy->mutex);
if (fgets(line, sizeof line, fancy->out) == NULL) exit(1);
- pthread_mutex_unlock(fancy->read_mutex);
-
pthread_mutex_lock(fancy->mutex);
arg = strtok_r(line, "\r\n\t ", &buffer);
if (arg == NULL) continue;
+ if (!strcmp(arg, "bestmove"))
+ {+ fancy->idle = 1;
+ fancy->taken = fancy->time;
+ fancy->stop = 0;
+ changed = 1;
+ continue;
+ }
+
+ if (fancy->stop != 0) continue;
+ if (strcmp(arg, "info")) continue;
+
ply = fancy->plies[fancy->i];
ply.depth = 0;
@@ -348,13 +357,16 @@
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, "lowerbound") || !strcmp(arg, "upperbound"))
+ {+ changed = 0;
+ break;
+ }
if (!strcmp(arg, "depth"))
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
- if (arg == NULL || sscanf(arg, "%d", &ply.depth) != 1)
+ if (arg == NULL || moonfish_int(arg, &ply.depth) != 0 || ply.depth < 0)
{fprintf(stderr, "%s: malformed 'depth' in 'info' command\n", fancy->argv0);
exit(1);
@@ -365,12 +377,20 @@
if (!strcmp(arg, "pv"))
{+ changed = 1;
+ fancy->idle = 0;
+
i = 0;
while (i < sizeof fancy->pv - 1)
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
if (arg == NULL) break;
- moonfish_from_uci(&ply.chess, &move, arg);
+ if (moonfish_from_uci(&ply.chess, &move, arg) != 0)
+ {+ fprintf(stderr, "%s: invalid move: %s\n", fancy->argv0, arg);
+ exit(1);
+ }
+ if (i == 0) strcpy(ply.best, arg);
moonfish_to_san(&ply.chess, &move, san);
length = strlen(san);
if (i + length > sizeof fancy->pv - 2) break;
@@ -380,32 +400,29 @@
i += length;
}
- 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;
+ ply.chess = fancy->plies[fancy->i].chess;
+ continue;
}
if (!strcmp(arg, "wdl"))
{+ changed = 1;
+ fancy->idle = 0;
+
arg = strtok_r(NULL, "\r\n\t ", &buffer);
- if (arg == NULL || sscanf(arg, "%d", &ply.white) != 1)
+ if (arg == NULL || moonfish_int(arg, &ply.white) != 0 || ply.white < 0)
{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)
+ if (arg == NULL || moonfish_int(arg, &ply.draw) != 0 || ply.draw < 0)
{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)
+ if (arg == NULL || moonfish_int(arg, &ply.black) != 0 || ply.black < 0)
{fprintf(stderr, "%s: malformed 'wdl' loss in 'info' command\n", fancy->argv0);
exit(1);
@@ -423,7 +440,24 @@
continue;
}
+ if (!strcmp(arg, "time"))
+ {+ changed = 1;
+ fancy->idle = 0;
+
+ arg = strtok_r(NULL, "\r\n\t ", &buffer);
+ if (arg == NULL || moonfish_int(arg, &fancy->taken) != 0 || fancy->taken < 0)
+ {+ fprintf(stderr, "%s: malformed 'time' in 'info' command\n", fancy->argv0);
+ exit(1);
+ }
+
+ continue;
+ }
+
if (strcmp(arg, "score")) continue;
+ changed = 1;
+ fancy->idle = 0;
arg = strtok_r(NULL, "\r\n\t ", &buffer);
if (arg == NULL) break;
@@ -431,7 +465,7 @@
if (!strcmp(arg, "cp"))
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
- if (arg == NULL || sscanf(arg, "%d", &score) != 1)
+ if (arg == NULL || moonfish_int(arg, &score) != 0)
{fprintf(stderr, "%s: malformed 'cp' in 'info score' command\n", fancy->argv0);
exit(1);
@@ -459,7 +493,7 @@
if (!strcmp(arg, "mate"))
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
- if (arg == NULL || sscanf(arg, "%d", &score) != 1)
+ if (arg == NULL || moonfish_int(arg, &score) != 0)
{fprintf(stderr, "%s: malformed 'mate' in 'info score' command\n", fancy->argv0);
exit(1);
@@ -476,6 +510,8 @@
continue;
}
}
+
+ if (changed != 0) fancy->plies[fancy->i] = ply;
}
}
@@ -507,11 +543,10 @@
{int i;
- pthread_mutex_lock(fancy->read_mutex);
+ fancy->taken = 0;
+ if (fancy->idle == 0) fancy->stop = 1;
fprintf(fancy->in, "stop\n");
- fprintf(fancy->in, "isready\n");
- moonfish_wait(fancy->out, "readyok");
fprintf(fancy->in, "position ");
if (fancy->fen == NULL) fprintf(fancy->in, "startpos");
@@ -525,14 +560,11 @@
}
fprintf(fancy->in, "\n");
-
- fprintf(fancy->in, "isready\n");
- moonfish_wait(fancy->out, "readyok");
fprintf(fancy->in, "go movetime %d\n", fancy->time);
fancy->pv[0] = 0;
- pthread_mutex_unlock(fancy->read_mutex);
+ moonfish_fancy(fancy);
}
static void moonfish_go(struct moonfish_fancy *fancy)
@@ -547,10 +579,29 @@
moonfish_analyse(fancy);
}
+static void moonfish_play(struct moonfish_fancy *fancy, struct moonfish_move *move)
+{+ if (fancy->i + 1 >= (int) (sizeof fancy->plies / sizeof *fancy->plies)) return;
+
+ fancy->i++;
+ 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;
+ fancy->plies[fancy->i].best[0] = 0;
+
+ moonfish_to_uci(&fancy->plies[fancy->i].chess, move, fancy->plies[fancy->i].name);
+ moonfish_to_san(&fancy->plies[fancy->i].chess, move, fancy->plies[fancy->i].san);
+
+ fancy->plies[fancy->i].chess = move->chess;
+ fancy->x = 0;
+
+ moonfish_go(fancy);
+}
+
int main(int argc, char **argv)
{static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_mutex_t read_mutex = PTHREAD_MUTEX_INITIALIZER;
static char *format = "<UCI-options>... [--] <cmd> <args>...";
static struct moonfish_arg args[] =
{@@ -570,6 +621,7 @@
int command_count;
char *value;
char **options;
+ int i;
moonfish_spawner(argv[0]);
@@ -581,7 +633,18 @@
for (;;)
{value = strchr(*command, '=');
- if (value == NULL) break;
+ if (value == NULL)
+ {+ if (!strcmp(*command, "--"))
+ {+ command_count--;
+ command++;
+
+ if (command_count <= 0) moonfish_usage(args, format, argv[0]);
+ }
+
+ break;
+ }
if (strchr(*command, '\n') != NULL || strchr(*command, '\r') != NULL) moonfish_usage(args, format, argv[0]);
@@ -589,15 +652,6 @@
command++;
if (command_count <= 0) moonfish_usage(args, format, argv[0]);
-
- if (!strcmp(*command, "--"))
- {- command_count--;
- command++;
-
- if (command_count <= 0) moonfish_usage(args, format, argv[0]);
- break;
- }
}
if (tcgetattr(0, &moonfish_termios))
@@ -640,9 +694,10 @@
fancy->argv0 = argv[0];
fancy->mutex = &mutex;
- fancy->read_mutex = &read_mutex;
fancy->offset = 0;
fancy->pv[0] = 0;
+ fancy->idle = 1;
+ fancy->stop = 0;
fancy->x = 0;
fancy->y = 0;
@@ -683,13 +738,8 @@
options++;
}
- fprintf(fancy->in, "isready\n");
- moonfish_wait(fancy->out, "readyok");
-
fprintf(fancy->in, "ucinewgame\n");
- moonfish_go(fancy);
-
printf("\n\n\n\n\n\n\n\n\n\n\n"); printf("\x1B[10A");@@ -705,6 +755,11 @@
if (scanf("[%d;%dR", &fancy->oy, &fancy->ox) != 2) return 1;+ printf("\x1B[?1000h");+ fflush(stdout);
+
+ moonfish_go(fancy);
+
error = pthread_create(&thread, NULL, &moonfish_start, fancy);
if (error != 0)
{@@ -712,11 +767,10 @@
exit(1);
}
- printf("\x1B[?1000h");- fflush(stdout);
-
for (ch0 = 0 ; ch0 != EOF ; ch0 = getchar())
{+ if (ch0 == 'q' || ch0 == 'Q') break;
+
if (ch0 != 0x1B) continue;
ch0 = getchar();
if (ch0 == EOF) break;
@@ -731,7 +785,6 @@
pthread_mutex_lock(fancy->mutex);
fancy->i = 0;
moonfish_go(fancy);
- moonfish_fancy(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -742,7 +795,6 @@
pthread_mutex_lock(fancy->mutex);
fancy->i = fancy->count - 1;
moonfish_go(fancy);
- moonfish_fancy(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -753,7 +805,6 @@
pthread_mutex_lock(fancy->mutex);
fancy->i++;
moonfish_go(fancy);
- moonfish_fancy(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -764,7 +815,6 @@
pthread_mutex_lock(fancy->mutex);
fancy->i--;
moonfish_go(fancy);
- moonfish_fancy(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -809,11 +859,41 @@
if (y1 == 1 && x1 >= 21 && x1 <= 23)
{+ pthread_mutex_lock(fancy->mutex);
moonfish_bump(fancy);
- moonfish_fancy(fancy);
+ pthread_mutex_unlock(fancy->mutex);
continue;
}
+ if (y1 >= 2 && y1 <= 7 && x1 >= 21 && x1 <= 40)
+ {+ pthread_mutex_lock(fancy->mutex);
+ i = (fancy->offset + y1) * 2 - 3;
+ if (x1 > 30) i++;
+ if (i < fancy->count)
+ {+ fancy->i = i;
+ moonfish_go(fancy);
+ }
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ if (y1 == 8 && x1 >= 21 && x1 <= 40)
+ {+ pthread_mutex_lock(fancy->mutex);
+ if (fancy->plies[fancy->i].best[0] != 0)
+ {+ if (moonfish_from_uci(&fancy->plies[fancy->i].chess, &move, fancy->plies[fancy->i].best))
+ {+ fprintf(stderr, "%s: invalid best move: %s\n", fancy->argv0, fancy->plies[fancy->i].best);
+ exit(1);
+ }
+ moonfish_play(fancy, &move);
+ }
+ pthread_mutex_unlock(fancy->mutex);
+ }
+
if (fancy->x == 0) continue;
x1 /= 2;
@@ -826,22 +906,7 @@
if (moonfish_move_from(&fancy->plies[fancy->i].chess, &move, fancy->x, fancy->y, x1, y1) == 0)
{pthread_mutex_lock(fancy->mutex);
-
- fancy->i++;
- 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].chess, &move, fancy->plies[fancy->i].name);
- moonfish_to_san(&fancy->plies[fancy->i].chess, &move, fancy->plies[fancy->i].san);
-
- fancy->plies[fancy->i].chess = move.chess;
- fancy->x = 0;
- moonfish_fancy(fancy);
-
- moonfish_go(fancy);
-
+ moonfish_play(fancy, &move);
pthread_mutex_unlock(fancy->mutex);
}
else
@@ -849,10 +914,14 @@
pthread_mutex_lock(fancy->mutex);
if (ch0 == 0x20 && x1 == fancy->x && y1 == fancy->y)
+ {fancy->x = 0;
+ }
else
- fancy->x = x1,
+ {+ fancy->x = x1;
fancy->y = y1;
+ }
x1 = 0;
y1 = 0;
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -23,4 +23,6 @@
char **moonfish_args(struct moonfish_arg *args, char *rest_format, int argc, char **argv);
void moonfish_usage(struct moonfish_arg *args, char *rest_format, char *argv0);
+int moonfish_int(char *arg, int *result);
+
#endif
--- a/tools/utils.c
+++ b/tools/utils.c
@@ -12,6 +12,7 @@
#include <signal.h>
#include <pthread.h>
#include <sys/un.h>
+#include <limits.h>
#include "tools.h"
@@ -479,6 +480,19 @@
if (!strcmp(line, name))
return strtok_r(NULL, "\r\n\t ", &buffer);
}
+}
+
+int moonfish_int(char *arg, int *result)
+{+ char *end;
+ long int long_result;
+ errno = 0;
+ long_result = strtol(arg, &end, 10);
+ if (errno != 0 || *end != 0) return 1;
+ if (long_result < INT_MIN) return 1;
+ if (long_result > INT_MAX) return 1;
+ *result = long_result;
+ return 0;
}
static void moonfish_usage_to(struct moonfish_arg *args, char *rest_format, char *argv0, FILE *out)
--
⑨