ref: bb6c11a2064f2ee8d5853b7402bd5b65a7966f61
parent: 63d3844e193a3ca13548c44f02f95822781ef1f0
author: zamfofex <zamfofex@twdb.moe>
date: Tue Oct 8 21:13:06 EDT 2024
refactor and improve analysis TUI
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -164,8 +164,10 @@
}
while (white > 1)
- printf("\x1B[48;5;253m \x1B[0m\x1B[B\x08"),+ {+ printf("\x1B[48;5;253m \x1B[0m\x1B[B\x08");white -= 2;
+ }
}
static void moonfish_scoresheet_move(struct moonfish_fancy *fancy, int i)
@@ -224,17 +226,9 @@
{int i, j;
- if (fancy->plies[0].chess.white) i = 1;
- else i = 0;
+ i = fancy->offset * 2;
+ if (fancy->plies[0].chess.white != 0) i++;
- if (fancy->i + 2 - i < fancy->offset * 2 + 2)
- fancy->offset = (fancy->i + 2 - i) / 2 - 1;
- if (fancy->i + 2 - i > fancy->offset * 2 + 12)
- fancy->offset = (fancy->i + 2 - i) / 2 - 6;
- if (fancy->offset < 0) fancy->offset = 0;
-
- i += fancy->offset * 2;
-
for (j = 0 ; j < 6 ; j++)
{ printf("\x1B[23G");@@ -273,7 +267,7 @@
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", "");+ printf("\x1B[0K");}
static void moonfish_fancy(struct moonfish_fancy *fancy)
@@ -285,8 +279,7 @@
for (y = 0 ; y < 8 ; y++)
{ printf(" ");- for (x = 0 ; x < 8 ; x++)
- moonfish_fancy_square(fancy, x, y);
+ for (x = 0 ; x < 8 ; x++) moonfish_fancy_square(fancy, x, y);
printf("\x1B[0m\n");}
@@ -300,7 +293,7 @@
moonfish_evaluation(fancy);
printf("\x1B[%d;23H", fancy->oy + 7);- printf("best:%s%32s\n", fancy->pv, "");+ printf("best:%s\x1B[0K\n", fancy->pv);fflush(stdout);
}
@@ -520,10 +513,10 @@
static void moonfish_exit(void)
{+ if (moonfish_engine != NULL) fprintf(moonfish_engine, "quit\n");
tcsetattr(0, TCSANOW, &moonfish_termios);
- printf("\x1B[?1000l");+ printf("\n\x1B[?1000l");fflush(stdout);
- if (moonfish_engine != NULL) fprintf(moonfish_engine, "quit\n");
}
static void moonfish_signal(int signal)
@@ -579,6 +572,16 @@
moonfish_analyse(fancy);
}
+static void moonfish_scroll(struct moonfish_fancy *fancy)
+{+ int i;
+ i = fancy->i + 2;
+ if (fancy->plies[0].chess.white != 0) i--;
+ if (i < fancy->offset * 2 + 2) fancy->offset = i / 2 - 1;
+ if (i > fancy->offset * 2 + 12) fancy->offset = i / 2 - 6;
+ if (fancy->offset < 0) fancy->offset = 0;
+}
+
static void moonfish_play(struct moonfish_fancy *fancy, struct moonfish_move *move)
{if (fancy->i + 1 >= (int) (sizeof fancy->plies / sizeof *fancy->plies)) return;
@@ -596,6 +599,7 @@
fancy->plies[fancy->i].chess = move->chess;
fancy->x = 0;
+ moonfish_scroll(fancy);
moonfish_go(fancy);
}
@@ -625,6 +629,8 @@
moonfish_spawner(argv[0]);
+ /* handle command line arguments */
+
command = moonfish_args(args, format, argc, argv);
command_count = argc - (command - argv);
if (command_count < 1) moonfish_usage(args, format, argv[0]);
@@ -654,6 +660,8 @@
if (command_count <= 0) moonfish_usage(args, format, argv[0]);
}
+ /* set up terminal for displaying the user interface */
+
if (tcgetattr(0, &moonfish_termios))
{perror(argv[0]);
@@ -685,6 +693,26 @@
return 1;
}
+ printf("\n\n\n\n\n\n\n\n\n");+ printf("\x1B[8A");+
+ printf("\x1B[6n");+ fflush(stdout);
+
+ for (;;)
+ {+ ch = getchar();
+ if (ch == EOF) return 1;
+ if (ch == 0x1B) break;
+ }
+
+ if (scanf("[%d;%dR", &fancy->oy, &fancy->ox) != 2) return 1;+
+ printf("\x1B[?1000h");+ fflush(stdout);
+
+ /* initialise data structures */
+
fancy = malloc(sizeof *fancy);
if (fancy == NULL)
{@@ -727,6 +755,8 @@
moonfish_from_fen(&fancy->plies[0].chess, fancy->fen);
}
+ /* begin setting up UCI bot */
+
fprintf(fancy->in, "uci\n");
moonfish_wait(fancy->out, "uciok");
@@ -740,37 +770,21 @@
fprintf(fancy->in, "ucinewgame\n");
- printf("\n\n\n\n\n\n\n\n\n\n\n");- printf("\x1B[10A");-
- printf("\x1B[6n");- fflush(stdout);
-
- for (;;)
- {- ch = getchar();
- if (ch == EOF) return 1;
- if (ch == 0x1B) break;
- }
-
- if (scanf("[%d;%dR", &fancy->oy, &fancy->ox) != 2) return 1;-
- printf("\x1B[?1000h");- fflush(stdout);
-
moonfish_go(fancy);
+ /* start thread to communicate with the bot */
+
error = pthread_create(&thread, NULL, &moonfish_start, fancy);
if (error != 0)
{fprintf(stderr, "%s: %s\n", fancy->argv0, strerror(error));
- exit(1);
+ return 1;
}
+ /* main UI loop */
+
for (ch0 = 0 ; ch0 != EOF ; ch0 = getchar())
{- if (ch0 == 'q' || ch0 == 'Q') break;
-
if (ch0 != 0x1B) continue;
ch0 = getchar();
if (ch0 == EOF) break;
@@ -779,158 +793,192 @@
ch0 = getchar();
if (ch0 == EOF) break;
+ /* handle up arrow */
if (ch0 == 'A')
{if (fancy->i == 0) continue;
pthread_mutex_lock(fancy->mutex);
fancy->i = 0;
+ moonfish_scroll(fancy);
moonfish_go(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
+ /* handle down arrow */
if (ch0 == 'B')
{if (fancy->i == fancy->count - 1) continue;
pthread_mutex_lock(fancy->mutex);
fancy->i = fancy->count - 1;
+ moonfish_scroll(fancy);
moonfish_go(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
+ /* handle right arrow */
if (ch0 == 'C')
{if (fancy->i == fancy->count - 1) continue;
pthread_mutex_lock(fancy->mutex);
fancy->i++;
+ moonfish_scroll(fancy);
moonfish_go(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
+ /* handle left arrow */
if (ch0 == 'D')
{if (fancy->i == 0) continue;
pthread_mutex_lock(fancy->mutex);
fancy->i--;
+ moonfish_scroll(fancy);
moonfish_go(fancy);
pthread_mutex_unlock(fancy->mutex);
continue;
}
- if (ch0 != 0x4D) continue;
+ /* 'M' means "mouse button" */
+ /* (only handle them henceforth) */
+ if (ch0 != 'M') continue;
+
+ /* which mouse button? */
ch0 = getchar();
if (ch0 == EOF) break;
- if (ch0 == 0x20 && fancy->x == 0)
+ /* mouse 'x' coordinate */
+ ch = getchar();
+ if (ch == EOF) break;
+ x1 = ch - 0x21 - fancy->ox;
+
+ /* mouse 'y' coordinate */
+ ch = getchar();
+ if (ch == EOF) break;
+ y1 = ch - 0x21 - fancy->oy + 2;
+
+ /* handle scroll up */
+ if (ch0 == 0x60)
{pthread_mutex_lock(fancy->mutex);
-
- ch = getchar();
- if (ch == EOF) break;
- fancy->x = ch - 0x21 - fancy->ox;
-
- ch = getchar();
- if (ch == EOF) break;
- fancy->y = ch - 0x21 - fancy->oy + 2;
-
- fancy->x /= 2;
-
- if (fancy->x < 1 || fancy->x > 8) fancy->x = 0;
- if (fancy->y < 1 || fancy->y > 8) fancy->x = 0;
-
- moonfish_fancy(fancy);
-
+ if (fancy->offset > 0)
+ {+ fancy->offset--;
+ moonfish_fancy(fancy);
+ }
pthread_mutex_unlock(fancy->mutex);
-
continue;
}
- if (ch0 == 0x20 || ch0 == 0x23)
+ /* handle scroll down */
+ if (ch0 == 0x61)
{- ch = getchar();
- if (ch == EOF) break;
- x1 = ch - 0x21 - fancy->ox;
-
- ch = getchar();
- if (ch == EOF) break;
- y1 = ch - 0x21 - fancy->oy + 2;
-
- if (y1 == 1 && x1 >= 21 && x1 <= 23)
+ pthread_mutex_lock(fancy->mutex);
+ if (fancy->offset < fancy->count / 2 - 6)
{- pthread_mutex_lock(fancy->mutex);
- moonfish_bump(fancy);
- pthread_mutex_unlock(fancy->mutex);
- continue;
+ fancy->offset++;
+ moonfish_fancy(fancy);
}
-
- if (y1 >= 2 && y1 <= 7 && x1 >= 21 && x1 <= 40)
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* "(+)" button clicked */
+ if (ch0 == 0x20 && y1 == 1 && x1 >= 21 && x1 <= 23)
+ {+ pthread_mutex_lock(fancy->mutex);
+ moonfish_bump(fancy);
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* move name clicked (on scoresheet) */
+ if (ch0 == 0x20 && y1 >= 2 && y1 <= 7 && x1 >= 21 && x1 <= 40)
+ {+ pthread_mutex_lock(fancy->mutex);
+ i = (fancy->offset + y1) * 2 - 4;
+ if (fancy->plies[0].chess.white) i++;
+ if (x1 > 30) i++;
+ if (i < fancy->count)
{- 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;
+ fancy->i = i;
+ moonfish_go(fancy);
}
-
- if (y1 == 8 && x1 >= 21 && x1 <= 40)
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* "best move" button clicked */
+ if (ch0 == 0x20 && y1 == 8 && x1 >= 21 && x1 <= 40)
+ {+ pthread_mutex_lock(fancy->mutex);
+ if (fancy->plies[fancy->i].best[0] != 0)
{- 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))
{- 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);
+ fprintf(stderr, "%s: invalid best move: %s\n", fancy->argv0, fancy->plies[fancy->i].best);
+ return 1;
}
- pthread_mutex_unlock(fancy->mutex);
- }
-
- if (fancy->x == 0) continue;
-
- x1 /= 2;
-
- if (x1 < 1 || x1 > 8) x1 = 0;
- if (y1 < 1 || y1 > 8) x1 = 0;
-
- if (x1 == 0) continue;
-
- if (moonfish_move_from(&fancy->plies[fancy->i].chess, &move, fancy->x, fancy->y, x1, y1) == 0)
- {- pthread_mutex_lock(fancy->mutex);
moonfish_play(fancy, &move);
- pthread_mutex_unlock(fancy->mutex);
}
- else
- {- pthread_mutex_lock(fancy->mutex);
-
- if (ch0 == 0x20 && x1 == fancy->x && y1 == fancy->y)
- {- fancy->x = 0;
- }
- else
- {- fancy->x = x1;
- fancy->y = y1;
- }
-
- x1 = 0;
- y1 = 0;
-
- moonfish_fancy(fancy);
-
- pthread_mutex_unlock(fancy->mutex);
- }
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
}
+
+ /* only handle clicks on the board henceforth */
+ if (x1 < 2 || x1 > 17 || y1 < 1 || y1 > 8) continue;
+ x1 /= 2;
+
+ pthread_mutex_lock(fancy->mutex);
+
+ /* mouse down with no square selected: select the square under the mouse */
+ if (ch0 == 0x20 && fancy->x == 0)
+ {+ fancy->x = x1;
+ fancy->y = y1;
+ moonfish_fancy(fancy);
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* only handle cases where there a square selected henceforth */
+ if (fancy->x == 0)
+ {+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* handle mouse down: if the clicked square is the selected square, deselect it */
+ if (ch0 == 0x20 && x1 == fancy->x && y1 == fancy->y)
+ {+ fancy->x = 0;
+ moonfish_fancy(fancy);
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* handle mouse up or mouse down: if it forms a valid move, play it on the board */
+ if (ch0 == 0x20 || ch0 == 0x23)
+ if (moonfish_move_from(&fancy->plies[fancy->i].chess, &move, fancy->x, fancy->y, x1, y1) == 0)
+ {+ moonfish_play(fancy, &move);
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ /* handle mouse down: when there isn't a valid move under the mouse, just select the new square */
+ if (ch0 == 0x20)
+ {+ fancy->x = x1;
+ fancy->y = y1;
+ moonfish_fancy(fancy);
+ pthread_mutex_unlock(fancy->mutex);
+ continue;
+ }
+
+ pthread_mutex_unlock(fancy->mutex);
}
return 0;
--
⑨