Long-dead code removal: unused macro
[gnushogi.git] / gnushogi / cursesdsp.c
blobefa8bbb75d9cd1a5dab166756cd47c3bb5fe6add
1 /*
2 * FILE: cursesdsp.c
4 * Curses interface for GNU Shogi
6 * ----------------------------------------------------------------------
7 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
8 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
9 * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
11 * GNU SHOGI is based on GNU CHESS
13 * Copyright (c) 1988, 1989, 1990 John Stanback
14 * Copyright (c) 1992 Free Software Foundation
16 * This file is part of GNU SHOGI.
18 * GNU Shogi is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 3 of the License,
21 * or (at your option) any later version.
23 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
24 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * for more details.
28 * You should have received a copy of the GNU General Public License along
29 * with GNU Shogi; see the file COPYING. If not, see
30 * <http://www.gnu.org/licenses/>.
31 * ----------------------------------------------------------------------
34 /* request *snprintf prototypes */
35 #define _POSIX_C_SOURCE 200112L
37 #include "gnushogi.h"
39 #include <ctype.h>
40 #include <signal.h>
41 #include <stdio.h>
42 #include <stdarg.h>
44 #include <sys/param.h>
45 #include <sys/types.h>
46 #include <sys/file.h>
47 #include <curses.h>
49 #if HAVE_UNISTD_H
50 #include <unistd.h>
51 #endif
53 #if HAVE_SYS_FILIO_H
54 /* Definition of FIONREAD */
55 #include <sys/filio.h>
56 #endif
58 #if HAVE_ERRNO_H
59 /* Definition of errno(). */
60 #include <errno.h>
61 #endif
63 #define FLUSH_SCANW fflush(stdout), scanw
65 #define MARGIN (5)
66 #define TAB (58)
68 #define VIR_C(s) ((flag.reverse) ? (NO_COLS - 1 - column(s)) : column(s))
69 #define VIR_R(s) ((flag.reverse) ? (NO_ROWS - 1 - row(s)) : row(s))
71 /****************************************
72 * forward declarations
73 ****************************************/
75 /* FIXME: change this name, puh-leeze! */
76 static void UpdateCatched(void);
77 static void DrawPiece(short sq);
78 static void ShowScore(short score);
79 static void Curses_UpdateDisplay(short f, short t, short redraw, short isspec);
80 static void Curses_Die(int sig);
81 static void Curses_ShowSidetoMove(void);
83 /****************************************
84 * Trivial output functions.
85 ****************************************/
87 static void
88 ClearEoln(void)
90 clrtoeol();
91 refresh();
95 static void
96 Curses_ClearScreen(void)
98 clear();
99 refresh();
103 static void
104 gotoXY(short x, short y)
106 move(y - 1, x - 1);
110 static void
111 ClearMessage(void)
113 gotoXY(TAB, 6);
114 ClearEoln();
117 static void
118 Curses_ShowCurrentMove(short pnt, short f, short t)
120 algbr(f, t, 0);
121 gotoXY(TAB, 7);
122 printw("(%2d) %5s ", pnt, mvstr[0]);
126 static void
127 Curses_ShowDepth(char ch)
129 gotoXY(TAB, 4);
130 printw("Depth= %d%c ", Sdepth, ch);
131 ClearEoln();
135 static void
136 Curses_ShowGameType(void)
138 if (flag.post)
140 gotoXY(TAB, 20);
141 printw("%c vs. %c", GameType[black], GameType[white]);
146 static void
147 ShowHeader(void)
149 gotoXY(TAB, 2);
150 printw("GNU Shogi %s", PACKAGE_VERSION);
154 static void
155 Curses_ShowLine(unsigned short *bstline)
160 static void
161 _vprintw(const char *format, va_list ap)
163 static char buffer[60];
164 vsnprintf(buffer, sizeof(buffer), format, ap);
165 printw("%s", buffer);
168 static void
169 Curses_ShowMessage(char *format, ...)
171 va_list ap;
172 va_start(ap, format);
173 gotoXY(TAB, 6);
174 _vprintw(format, ap);
175 va_end(ap);
176 ClearEoln();
179 static void
180 Curses_AlwaysShowMessage(const char *format, ...)
182 va_list ap;
183 va_start(ap, format);
184 gotoXY(TAB, 6);
185 _vprintw(format, ap);
186 va_end(ap);
187 ClearEoln();
191 static void
192 Curses_Printf(const char *format, ...)
194 va_list ap;
195 va_start(ap, format);
196 _vprintw(format, ap);
197 va_end(ap);
201 static void
202 Curses_doRequestInputString(const char* fmt, char* buffer)
204 FLUSH_SCANW(fmt, buffer);
208 static int
209 Curses_GetString(char* sx)
211 fflush(stdout);
212 return (getstr(sx) == ERR);
216 static void
217 Curses_ShowNodeCnt(long NodeCnt)
219 gotoXY(TAB, 22);
220 /* printw("Nodes = %8ld, Nodes/Sec = %5ld", NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0); */
221 printw("n = %ld n/s = %ld",
222 NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0);
223 ClearEoln();
227 static void
228 Curses_ShowPatternCount(short side, short n)
230 if (flag.post)
232 gotoXY(TAB + 10 + 3 * side, 20); /* CHECKME */
234 if (n >= 0)
235 printw("%3d", n);
236 else
237 printw(" ");
242 static void
243 ShowPlayers(void)
245 gotoXY(5, ((flag.reverse) ? (5 + 2*NO_ROWS) : 2));
246 printw("%s", (computer == white) ? "Computer" : "Human ");
247 gotoXY(5, ((flag.reverse) ? 2 : (5 + 2*NO_ROWS)));
248 printw("%s", (computer == black) ? "Computer" : "Human ");
252 static void
253 Curses_ShowPrompt(void)
255 Curses_ShowSidetoMove();
256 gotoXY(TAB, 17);
257 printw("Your move is? ");
258 ClearEoln();
262 static void
263 Curses_ShowResponseTime(void)
265 if (flag.post)
267 short TCC = TCcount;
268 gotoXY(TAB, 21);
269 printw("%ld, %d, %ld, %ld, %ld, %d",
270 ResponseTime, TCC, TCleft, ExtraTime, et, flag.timeout);
271 ClearEoln();
276 static void
277 Curses_ShowResults(short score, unsigned short *bstline, char ch)
279 unsigned char d, ply;
281 if (flag.post)
283 Curses_ShowDepth(ch);
284 ShowScore(score);
285 d = 7;
287 for (ply = 1; bstline[ply] > 0; ply++)
289 if (ply % 2 == 1)
291 gotoXY(TAB, ++d);
292 ClearEoln();
295 algbr((short) bstline[ply] >> 8,
296 (short) bstline[ply] & 0xFF, 0);
297 printw("%5s ", mvstr[0]);
300 ClearEoln();
302 while (d < 13)
304 gotoXY(TAB, ++d);
305 ClearEoln();
311 static void
312 ShowScore(short score)
314 gotoXY(TAB, 5);
315 printw("Score= %d", score);
316 ClearEoln();
320 static void
321 Curses_ShowSidetoMove(void)
323 gotoXY(TAB, 14);
324 printw("%2d: %s", 1 + GameCnt / 2, ColorStr[player]);
325 ClearEoln();
329 static void
330 Curses_ShowStage(void)
332 gotoXY(TAB, 19);
333 printw("Stage= %2d%c B= %2d W= %2d",
334 stage, flag.tsume?'T':' ', balance[black], balance[white]);
335 ClearEoln();
338 /****************************************
339 * End of trivial output routines.
340 ****************************************/
342 static void
343 Curses_Initialize(void)
345 signal(SIGINT, Curses_Die);
346 signal(SIGQUIT, Curses_Die);
347 initscr();
348 crmode();
352 static void
353 Curses_ExitShogi(void)
355 if (!nolist)
356 ListGame();
358 gotoXY(1, 24);
360 refresh();
361 nocrmode();
362 endwin();
364 exit(0);
368 static void
369 Curses_Die(int sig)
371 char s[80];
373 signal(SIGINT, SIG_IGN);
374 signal(SIGQUIT, SIG_IGN);
376 Curses_ShowMessage("Abort? ");
377 FLUSH_SCANW("%s", s);
379 if (strcmp(s, "yes") == 0)
380 Curses_ExitShogi();
382 signal(SIGINT, Curses_Die);
383 signal(SIGQUIT, Curses_Die);
387 static void
388 Curses_TerminateSearch(int sig)
390 signal(SIGINT, SIG_IGN);
391 signal(SIGQUIT, SIG_IGN);
393 if (!flag.timeout)
394 flag.musttimeout = true;
396 Curses_ShowMessage("Terminate Search");
397 flag.bothsides = false;
398 signal(SIGINT, Curses_Die);
399 signal(SIGQUIT, Curses_Die);
403 static void
404 Curses_help(void)
406 Curses_ClearScreen();
407 printw("GNU Shogi %s command summary\n", PACKAGE_VERSION);
408 printw("-------------------------------"
409 "---------------------------------\n");
410 printw("7g7f move from 7g to 7f quit Exit Shogi\n");
411 printw("S6h move silver to 6h beep turn %s\n", (flag.beep) ? "OFF" : "ON");
412 printw("2d2c+ move to 2c and promote\n");
413 printw("P*5e drop pawn to 5e easy turn %s\n", (flag.easy) ? "OFF" : "ON");
414 printw("tsume toggle tsume mode hash turn %s\n", (flag.hash) ? "OFF" : "ON");
415 printw("bd redraw board reverse board display\n");
416 printw("list game to shogi.lst book turn %s used %d of %d\n", (Book) ? "OFF" : "ON", bookcount, BOOKSIZE);
417 printw("undo undo last ply remove take back a move\n");
418 printw("edit edit board force toggle manual move mode\n");
419 printw("switch sides with computer both computer match\n");
420 printw("black computer plays black white computer plays white\n");
421 printw("depth set search depth clock set time control\n");
422 printw("post principle variation hint suggest a move\n", (flag.post) ? "OFF" : "ON");
423 printw("save game to file get game from file\n");
424 printw("random randomize play new start new game\n");
425 gotoXY(10, 20);
426 printw("Computer: %s", ColorStr[computer]);
427 gotoXY(10, 21);
428 printw("Opponent: %s", ColorStr[opponent]);
429 gotoXY(10, 22);
430 printw("Level: %ld", MaxResponseTime/100);
431 gotoXY(10, 23);
432 printw("Easy mode: %s", (flag.easy) ? "ON" : "OFF");
433 gotoXY(25, 23);
434 printw("Tsume: %s", (flag.tsume) ? "ON" : "OFF");
435 gotoXY(40, 20);
436 printw("Depth: %d", MaxSearchDepth);
437 gotoXY(40, 21);
438 printw("Random: %s", (dither) ? "ON" : "OFF");
439 gotoXY(40, 22);
440 printw("Transposition table: %s", (flag.hash) ? "ON" : "OFF");
441 gotoXY(40, 23);
442 printw("Hit <RET> to return: ");
443 gotoXY(10, 24);
444 printw("Time Control %s %d moves %d sec %d add %d depth\n", (TCflag) ? "ON" : "OFF",
445 TimeControl.moves[black],
446 TimeControl.clock[black] / 100,
447 OperatorTime, MaxSearchDepth);
449 refresh();
451 #ifdef BOGUS
452 fflush(stdin); /* what is this supposed to do?? */
453 #endif /* BOGUS */
455 getchar();
456 Curses_ClearScreen();
457 Curses_UpdateDisplay(0, 0, 1, 0);
461 static const short x0[2] = { MARGIN + 5*NO_COLS + 4, 2 };
462 static const short y0[2] = { 4 + 2 * (NO_ROWS - 1), 4 };
466 * Set up a board position. Pieces are entered by typing the piece followed
467 * by the location. For example, N3f will place a knight on square 3f.
468 * P* will put a pawn to the captured pieces.
471 static void
472 Curses_EditBoard(void)
474 short a, c, sq, i, found;
475 short r = 0;
476 char s[80];
478 flag.regularstart = true;
479 Book = BOOKFAIL;
480 Curses_ClearScreen();
481 Curses_UpdateDisplay(0, 0, 1, 0);
482 gotoXY(TAB, 11);
483 printw(". Exit to main\n");
484 gotoXY(TAB, 12);
485 printw("# Clear board\n");
486 gotoXY(TAB, 13);
487 printw("c Change sides\n");
488 gotoXY(TAB, 7);
489 printw("Enter piece & location: ");
490 a = black;
492 while(1)
494 gotoXY(TAB, 4);
495 printw("Editing: %s", ColorStr[a]);
496 gotoXY(TAB + 2, 8);
497 ClearEoln();
498 FLUSH_SCANW("%s", s);
499 found = 0;
500 ClearMessage();
502 if (s[0] == '.')
503 break;
505 if (s[0] == '#')
507 for (sq = 0; sq < NO_SQUARES; sq++)
509 board[sq] = no_piece;
510 color[sq] = neutral;
511 DrawPiece(sq);
514 ClearCaptured();
515 UpdateCatched();
516 continue;
519 if (s[0] == 'c') {
520 a = otherside[a];
521 continue;
524 if (s[1] == '*')
526 for (i = NO_PIECES; i > no_piece; i--)
528 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
530 Captured[a][unpromoted[i]]++;
531 UpdateCatched();
532 found = 1;
533 break;
536 if (!found)
537 dsp->AlwaysShowMessage("Invalid piece type '%c'", s[0]);
538 continue;
541 c = COL_NUM(s[1]);
542 r = ROW_NUM(s[2]);
544 if ((c < 0) || (c >= NO_COLS) || (r < 0) || (r >= NO_ROWS)) {
545 dsp->AlwaysShowMessage("Out-of-board '%c%c'", s[1], s[2]);
546 continue;
549 sq = locn(r, c);
551 for (i = NO_PIECES; i > no_piece; i--)
553 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
555 color[sq] = a;
556 if (s[3] == '+')
557 board[sq] = promoted[i];
558 else
559 board[sq] = unpromoted[i];
561 found = 1;
562 break;
566 if (!found)
567 dsp->AlwaysShowMessage("Invalid piece type '%c'", s[0]);
569 DrawPiece(sq);
572 for (sq = 0; sq < NO_SQUARES; sq++)
573 Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
575 GameCnt = 0;
576 Game50 = 1;
577 ZeroRPT();
578 Sdepth = 0;
579 InitializeStats();
580 Curses_ClearScreen();
581 Curses_UpdateDisplay(0, 0, 1, 0);
585 static void
586 UpdateCatched()
588 short side;
590 for (side = black; side <= white; side++)
592 short x, y, piece, cside, k;
594 cside = flag.reverse ? (side ^ 1) : side;
595 x = x0[cside];
596 y = y0[cside];
597 k = 0;
599 for (piece = pawn; piece <= king; piece++)
601 short n;
603 if ((n = Captured[side][piece]))
605 gotoXY(x, y);
606 printw("%i%c", n, pxx[piece]);
608 if (cside == black)
609 y--;
610 else
611 y++;
613 else
615 k++;
619 while (k)
621 k--;
622 gotoXY(x, y);
623 printw(" ");
625 if (cside == black)
626 y--;
627 else
628 y++;
632 refresh();
636 static void
637 Curses_SearchStartStuff(short side)
639 short i;
641 signal(SIGINT, Curses_TerminateSearch);
642 signal(SIGQUIT, Curses_TerminateSearch);
644 for (i = 4; i < 14; i++) /* CHECKME */
646 gotoXY(TAB, i);
647 ClearEoln();
652 static void
653 Curses_OutputMove(void)
656 Curses_UpdateDisplay(root->f, root->t, 0, (short) root->flags);
657 gotoXY(TAB, 16);
659 if (flag.illegal)
661 printw("Illegal position.");
662 return;
665 printw("My move is: %5s", mvstr[0]);
667 if (flag.beep)
668 putchar(7);
670 ClearEoln();
672 gotoXY(TAB, 18);
674 if (root->flags & draw)
675 printw("Drawn game!");
676 else if (root->score == -(SCORE_LIMIT + 999))
677 printw("Opponent mates!");
678 else if (root->score == SCORE_LIMIT + 998)
679 printw("Computer mates!");
680 #ifdef VERYBUGGY
681 else if (root->score < -SCORE_LIMIT)
682 printw("Opp: mate in %d!", SCORE_LIMIT + 999 + root->score - 1);
683 else if (root->score > SCORE_LIMIT)
684 printw("Comp: mate in %d!", SCORE_LIMIT + 998 - root->score - 1);
685 #endif /* VERYBUGGY */
687 ClearEoln();
689 if (flag.post)
691 short h, l, t;
693 h = TREE;
694 l = 0;
695 t = TREE >> 1;
697 while (l != t)
699 if (Tree[t].f || Tree[t].t)
700 l = t;
701 else
702 h = t;
704 t = (l + h) >> 1;
707 Curses_ShowNodeCnt(NodeCnt);
708 gotoXY(TAB, 23);
709 printw("Max Tree = %5d", t);
710 ClearEoln();
713 Curses_ShowSidetoMove();
717 static void
718 Curses_UpdateClocks(void)
720 short m, s;
721 long dt;
723 if (TCflag)
725 m = (short) ((dt = (TimeControl.clock[player] - et)) / 6000);
726 s = (short) ((dt - 6000 * (long) m) / 100);
728 else
730 m = (short) ((dt = et) / 6000);
731 s = (short) (et - 6000 * (long) m) / 100;
734 if (m < 0)
735 m = 0;
737 if (s < 0)
738 s = 0;
740 if (player == black)
741 gotoXY(20, (flag.reverse) ? 2 : (5 + 2*NO_ROWS));
742 else
743 gotoXY(20, (flag.reverse) ? (5 + 2*NO_ROWS) : 2);
745 /* printw("%d:%02d %ld ", m, s, dt); */
746 printw("%d:%02d ", m, s);
748 if (flag.post)
749 Curses_ShowNodeCnt(NodeCnt);
751 refresh();
755 static void
756 DrawPiece(short sq)
758 char y;
759 char piece, l, r, p;
761 if (color[sq] == neutral)
763 l = r = ' ';
765 else if (flag.reverse ^ (color[sq] == black))
767 l = '/';
768 r = '\\';
770 else
772 l = '\\', r = '/';
775 piece = board[sq];
777 if (is_promoted[(int)piece])
779 p = '+';
780 y = pxx[unpromoted[(int)piece]];
782 else
784 p = ' ';
785 y = pxx[(int)piece];
788 gotoXY(MARGIN + 3 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
789 printw("%c%c%c%c", l, p, y, r);
794 * Curses_ShowPostnValue(): must have called ExaminePosition() first
796 static void
797 Curses_ShowPostnValue(short sq)
799 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq))); /* CHECKME */
800 (void) ScorePosition(color[sq]);
802 if (color[sq] != neutral)
803 #if defined SAVE_SVALUE
805 printw("??? ");
807 #else
809 printw("%3d ", svalue[sq]);
811 #endif
812 else
814 printw(" ");
819 static void
820 Curses_ShowPostnValues(void)
822 short sq, score;
824 ExaminePosition(opponent);
826 for (sq = 0; sq < NO_SQUARES; sq++)
827 Curses_ShowPostnValue(sq);
829 score = ScorePosition(opponent);
830 gotoXY(TAB, 5);
831 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
832 mtl[computer], pscore[computer], GameType[computer],
833 mtl[opponent], pscore[opponent], GameType[opponent]);
835 ClearEoln();
839 static void
840 Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
842 short i, sq, z;
843 int j;
845 if (redraw)
847 ShowHeader();
848 ShowPlayers();
850 i = 2;
851 gotoXY(MARGIN, ++i);
853 printw(" +");
854 for (j=0; j<NO_COLS; j++)
855 printw("----+");
857 while (i <= 1 + 2*NO_ROWS)
859 gotoXY(MARGIN, ++i);
861 if (flag.reverse)
862 z = (i / 2) - 1;
863 else
864 z = NO_ROWS + 2 - ((i + 1) / 2);
866 printw("%c |", ROW_NAME(z+1));
867 for (j=0; j<NO_COLS; j++)
868 printw(" |");
870 gotoXY(MARGIN, ++i);
872 if (i < 2 + 2*NO_ROWS)
874 printw(" +");
875 for (j=0; j<NO_COLS; j++)
876 printw("----+");
880 printw(" +");
881 for (j=0; j<NO_COLS; j++)
882 printw("----+");
884 gotoXY(MARGIN, 4 + 2*NO_ROWS);
885 printw(" ");
886 #ifndef MINISHOGI
887 if (flag.reverse)
888 printw(" 1 2 3 4 5 6 7 8 9");
889 else
890 printw(" 9 8 7 6 5 4 3 2 1");
891 #else
892 if (flag.reverse)
893 printw(" 1 2 3 4 5");
894 else
895 printw(" 5 4 3 2 1");
896 #endif
898 for (sq = 0; sq < NO_SQUARES; sq++)
899 DrawPiece(sq);
901 else /* not redraw */
903 if (f < NO_SQUARES)
904 DrawPiece(f);
906 DrawPiece(t & 0x7f);
909 if ((isspec & capture) || (isspec & dropmask) || redraw)
911 short side;
913 for (side = black; side <= white; side++)
915 short x, y, piece, cside, k;
916 cside = flag.reverse ? (side ^ 1) : side;
917 x = x0[cside];
918 y = y0[cside];
919 k = 0;
921 for (piece = pawn; piece <= king; piece++)
923 short n;
925 if ((n = Captured[side][piece]))
927 gotoXY(x, y);
928 printw("%i%c", n, pxx[piece]);
930 if (cside == black) y--; else y++;
932 else
934 k++;
938 while (k)
940 k--;
941 gotoXY(x, y);
942 printw(" ");
944 if (cside == black)
945 y--;
946 else
947 y++;
952 refresh();
956 static void
957 Curses_ChangeAlphaWindow(void)
959 Curses_ShowMessage("WAwindow = ");
960 FLUSH_SCANW("%hd", &WAwindow);
961 Curses_ShowMessage("BAwindow = ");
962 FLUSH_SCANW("%hd", &BAwindow);
966 static void
967 Curses_ChangeBetaWindow(void)
969 Curses_ShowMessage("WBwindow = ");
970 FLUSH_SCANW("%hd", &WBwindow);
971 Curses_ShowMessage("BBwindow = ");
972 FLUSH_SCANW("%hd", &BBwindow);
976 static void
977 Curses_GiveHint(void)
979 char s[40];
981 if (hint)
983 algbr((short) (hint >> 8), (short) (hint & 0xFF), 0);
984 strcpy(s, "try ");
985 strcat(s, mvstr[0]);
986 Curses_ShowMessage(s);
988 else
990 Curses_ShowMessage("I have no idea.\n");
995 static void
996 Curses_ChangeSearchDepth(char* sx)
998 Curses_ShowMessage("depth = ");
999 FLUSH_SCANW("%hd", &MaxSearchDepth);
1000 TCflag = !(MaxSearchDepth > 0);
1004 static void
1005 Curses_ChangeHashDepth(void)
1007 Curses_ShowMessage("hashdepth = ");
1008 FLUSH_SCANW("%hd", &HashDepth);
1009 Curses_ShowMessage("MoveLimit = ");
1010 FLUSH_SCANW("%hd", &HashMoveLimit);
1014 static void
1015 Curses_SetContempt(void)
1017 Curses_ShowMessage("contempt = ");
1018 FLUSH_SCANW("%hd", &contempt);
1022 static void
1023 Curses_ChangeXwindow(void)
1025 Curses_ShowMessage("xwndw= ");
1026 FLUSH_SCANW("%hd", &xwndw);
1030 static void
1031 Curses_SelectLevel(char *sx)
1033 int item;
1035 Curses_ClearScreen();
1036 gotoXY(32, 2);
1037 printw("GNU Shogi %s", PACKAGE_VERSION);
1038 gotoXY(20, 4);
1039 printw(" 1. 40 moves in 5 minutes");
1040 gotoXY(20, 5);
1041 printw(" 2. 40 moves in 15 minutes");
1042 gotoXY(20, 6);
1043 printw(" 3. 40 moves in 30 minutes");
1044 gotoXY(20, 7);
1045 printw(" 4. all moves in 15 minutes");
1046 gotoXY(20, 8);
1047 printw(" 5. all moves in 30 minutes");
1048 gotoXY(20, 9);
1049 printw(" 6. all moves in 15 minutes, 30 seconds fischer clock");
1050 gotoXY(20, 10);
1051 printw(" 7. all moves in 30 minutes, 30 seconds fischer clock");
1052 gotoXY(20, 11);
1053 printw(" 8. 1 move in 1 minute");
1054 gotoXY(20, 12);
1055 printw(" 9. 1 move in 15 minutes");
1056 gotoXY(20, 13);
1057 printw("10. 1 move in 30 minutes");
1059 OperatorTime = 0;
1060 TCmoves = 40;
1061 TCminutes = 5;
1062 TCseconds = 0;
1064 gotoXY(20, 17);
1065 printw("Enter Level: ");
1066 refresh();
1067 FLUSH_SCANW("%d", &item);
1069 switch(item)
1071 case 1:
1072 TCmoves = 40;
1073 TCminutes = 5;
1074 break;
1076 case 2:
1077 TCmoves = 40;
1078 TCminutes = 15;
1079 break;
1081 case 3:
1082 TCmoves = 40;
1083 TCminutes = 30;
1084 break;
1086 case 4:
1087 TCmoves = 80;
1088 TCminutes = 15;
1089 flag.gamein = true;
1090 break;
1092 case 5:
1093 TCmoves = 80;
1094 TCminutes = 30;
1095 flag.gamein = true;
1096 break;
1098 case 6:
1099 TCmoves = 80;
1100 TCminutes = 15;
1101 TCadd = 3000;
1102 flag.gamein = true;
1103 break;
1105 case 7:
1106 TCmoves = 80;
1107 TCminutes = 30;
1108 TCadd = 3000;
1109 break;
1111 case 8:
1112 TCmoves = 1;
1113 TCminutes = 1;
1114 flag.onemove = true;
1115 break;
1117 case 9:
1118 TCmoves = 1;
1119 TCminutes = 15;
1120 flag.onemove = true;
1121 break;
1123 case 10:
1124 TCmoves = 1;
1125 TCminutes = 30;
1126 flag.onemove = true;
1127 break;
1130 TCflag = (TCmoves > 0);
1132 TimeControl.clock[black] = TimeControl.clock[white] = 0;
1134 SetTimeControl();
1135 Curses_ClearScreen();
1136 Curses_UpdateDisplay(0, 0, 1, 0);
1140 static void
1141 Curses_DoDebug(void)
1143 short c, p, sq, tp, tc, tsq, score;
1144 char s[40];
1146 ExaminePosition(opponent);
1147 Curses_ShowMessage("Enter piece: ");
1148 FLUSH_SCANW("%s", s);
1149 c = neutral;
1151 if ((s[0] == 'b') || (s[0] == 'B'))
1152 c = black;
1154 if ((s[0] == 'w') || (s[0] == 'W'))
1155 c = white;
1157 for (p = king; p > no_piece; p--)
1159 if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
1160 break;
1163 for (sq = 0; sq < NO_SQUARES; sq++)
1165 tp = board[sq];
1166 tc = color[sq];
1167 board[sq] = p;
1168 color[sq] = c;
1169 tsq = PieceList[c][1];
1170 PieceList[c][1] = sq;
1171 Curses_ShowPostnValue(sq);
1172 PieceList[c][1] = tsq;
1173 board[sq] = tp;
1174 color[sq] = tc;
1177 score = ScorePosition(opponent);
1178 gotoXY(TAB, 5);
1179 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
1180 mtl[computer], pscore[computer], GameType[computer],
1181 mtl[opponent], pscore[opponent], GameType[opponent]);
1183 ClearEoln();
1187 static void
1188 Curses_DoTable(short table[NO_SQUARES])
1190 short sq;
1191 ExaminePosition(opponent);
1193 for (sq = 0; sq < NO_SQUARES; sq++)
1195 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));
1196 printw("%3d ", table[sq]);
1201 static void
1202 Curses_PollForInput(void)
1204 int i;
1205 int nchar;
1207 if ((i = ioctl((int) 0, FIONREAD, &nchar)))
1209 perror("FIONREAD");
1210 fprintf(stderr,
1211 "You probably have a non-ANSI <ioctl.h>; "
1212 "see README. %d %d %x\n",
1213 i, errno, FIONREAD);
1214 exit(1);
1217 if (nchar)
1219 if (!flag.timeout)
1220 flag.back = true;
1222 flag.bothsides = false;
1227 static void
1228 Curses_SetupBoard(void)
1230 Curses_ShowMessage("'setup' command is not supported in Cursesmode");
1234 struct display curses_display =
1236 .ChangeAlphaWindow = Curses_ChangeAlphaWindow,
1237 .ChangeBetaWindow = Curses_ChangeBetaWindow,
1238 .ChangeHashDepth = Curses_ChangeHashDepth,
1239 .ChangeSearchDepth = Curses_ChangeSearchDepth,
1240 .ChangeXwindow = Curses_ChangeXwindow,
1241 .ClearScreen = Curses_ClearScreen,
1242 .DoDebug = Curses_DoDebug,
1243 .DoTable = Curses_DoTable,
1244 .EditBoard = Curses_EditBoard,
1245 .ExitShogi = Curses_ExitShogi,
1246 .GiveHint = Curses_GiveHint,
1247 .Initialize = Curses_Initialize,
1248 .ShowNodeCnt = Curses_ShowNodeCnt,
1249 .OutputMove = Curses_OutputMove,
1250 .PollForInput = Curses_PollForInput,
1251 .SetContempt = Curses_SetContempt,
1252 .SearchStartStuff = Curses_SearchStartStuff,
1253 .SelectLevel = Curses_SelectLevel,
1254 .ShowCurrentMove = Curses_ShowCurrentMove,
1255 .ShowDepth = Curses_ShowDepth,
1256 .ShowGameType = Curses_ShowGameType,
1257 .ShowLine = Curses_ShowLine,
1258 .ShowMessage = Curses_ShowMessage,
1259 .AlwaysShowMessage = Curses_AlwaysShowMessage,
1260 .Printf = Curses_Printf,
1261 .doRequestInputString = Curses_doRequestInputString,
1262 .GetString = Curses_GetString,
1263 .SetupBoard = Curses_SetupBoard,
1264 .ShowPatternCount = Curses_ShowPatternCount,
1265 .ShowPostnValue = Curses_ShowPostnValue,
1266 .ShowPostnValues = Curses_ShowPostnValues,
1267 .ShowPrompt = Curses_ShowPrompt,
1268 .ShowResponseTime = Curses_ShowResponseTime,
1269 .ShowResults = Curses_ShowResults,
1270 .ShowSidetoMove = Curses_ShowSidetoMove,
1271 .ShowStage = Curses_ShowStage,
1272 .TerminateSearch = Curses_TerminateSearch,
1273 .UpdateClocks = Curses_UpdateClocks,
1274 .UpdateDisplay = Curses_UpdateDisplay,
1275 .help = Curses_help,