Curses: shift board one char to the right to leave enough space for captures.
[gnushogi.git] / gnushogi / cursesdsp.c
blob98cec52182a623525eff2e17e2545400337c27bb
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 <ctype.h>
38 #include <signal.h>
39 #include <stdio.h>
41 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/file.h>
44 #include <curses.h>
46 #include "gnushogi.h"
47 #include "cursesdsp.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 int mycnt1, mycnt2;
67 #define MARGIN (5)
68 #define TAB (58)
70 #define VIR_C(s) ((flag.reverse) ? (NO_COLS - 1 - column(s)) : column(s))
71 #define VIR_R(s) ((flag.reverse) ? (NO_ROWS - 1 - row(s)) : row(s))
73 unsigned short MV[MAXDEPTH];
74 int MSCORE;
75 char *DRAW;
77 /* Forward declarations. */
78 /* FIXME: change this name, puh-leeze! */
80 static void UpdateCatched(void);
81 static void DrawPiece(short sq);
82 static void ShowScore(short score);
84 /****************************************
85 * Trivial output functions.
86 ****************************************/
88 static void
89 ClearEoln(void)
91 clrtoeol();
92 refresh();
96 void
97 Curses_ClearScreen(void)
99 clear();
100 refresh();
104 static void
105 gotoXY(short x, short y)
107 move(y - 1, x - 1);
111 static void
112 ClearMessage(void)
114 gotoXY(TAB, 6);
115 ClearEoln();
119 void
120 Curses_ShowCurrentMove(short pnt, short f, short t)
122 algbr(f, t, false);
123 gotoXY(TAB, 7);
124 printw("(%2d) %5s ", pnt, mvstr[0]);
128 void
129 Curses_ShowDepth(char ch)
131 gotoXY(TAB, 4);
132 printw("Depth= %d%c ", Sdepth, ch);
133 ClearEoln();
137 void
138 Curses_ShowGameType(void)
140 if (flag.post)
142 gotoXY(TAB, 20);
143 printw("%c vs. %c", GameType[black], GameType[white]);
148 void
149 ShowHeader(void)
151 gotoXY(TAB, 2);
152 printw("GNU Shogi %s", PACKAGE_VERSION);
156 void
157 Curses_ShowLine(unsigned short *bstline)
162 void
163 Curses_ShowMessage(char *s)
165 gotoXY(TAB, 6);
166 printw("%s", s);
167 ClearEoln();
171 void
172 Curses_AlwaysShowMessage(const char *format, va_list ap)
174 static char buffer[60];
175 vsnprintf(buffer, sizeof(buffer), format, ap);
176 Curses_ShowMessage(buffer);
180 void
181 Curses_Printf(const char *format, va_list ap)
183 static char buffer[60];
184 vsnprintf(buffer, sizeof(buffer), format, ap);
185 printw("%s", buffer);
189 void
190 Curses_doRequestInputString(const char* fmt, char* buffer)
192 FLUSH_SCANW(fmt, buffer);
197 Curses_GetString(char* sx)
199 fflush(stdout);
200 return (getstr(sx) == ERR);
204 void
205 Curses_ShowNodeCnt(long NodeCnt)
207 gotoXY(TAB, 22);
208 /* printw("Nodes = %8ld, Nodes/Sec = %5ld", NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0); */
209 printw("n = %ld n/s = %ld",
210 NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0);
211 ClearEoln();
215 void
216 Curses_ShowPatternCount(short side, short n)
218 if (flag.post)
220 gotoXY(TAB + 10 + 3 * side, 20); /* CHECKME */
222 if (n >= 0)
223 printw("%3d", n);
224 else
225 printw(" ");
230 static void
231 ShowPlayers(void)
233 gotoXY(5, ((flag.reverse) ? (5 + 2*NO_ROWS) : 2));
234 printw("%s", (computer == white) ? "Computer" : "Human ");
235 gotoXY(5, ((flag.reverse) ? 2 : (5 + 2*NO_ROWS)));
236 printw("%s", (computer == black) ? "Computer" : "Human ");
240 void
241 Curses_ShowPrompt(void)
243 Curses_ShowSidetoMove();
244 gotoXY(TAB, 17);
245 printw("Your move is? ");
246 ClearEoln();
250 void
251 Curses_ShowResponseTime(void)
253 if (flag.post)
255 short TCC = TCcount;
256 gotoXY(TAB, 21);
257 printw("%ld, %d, %ld, %ld, %ld, %d",
258 ResponseTime, TCC, TCleft, ExtraTime, et, flag.timeout);
259 ClearEoln();
264 void
265 Curses_ShowResults(short score, unsigned short *bstline, char ch)
267 unsigned char d, ply;
269 if (flag.post)
271 Curses_ShowDepth(ch);
272 ShowScore(score);
273 d = 7;
275 for (ply = 1; bstline[ply] > 0; ply++)
277 if (ply % 2 == 1)
279 gotoXY(TAB, ++d);
280 ClearEoln();
283 algbr((short) bstline[ply] >> 8,
284 (short) bstline[ply] & 0xFF, false);
285 printw("%5s ", mvstr[0]);
288 ClearEoln();
290 while (d < 13)
292 gotoXY(TAB, ++d);
293 ClearEoln();
299 static void
300 ShowScore(short score)
302 gotoXY(TAB, 5);
303 printw("Score= %d", score);
304 ClearEoln();
308 void
309 Curses_ShowSidetoMove(void)
311 gotoXY(TAB, 14);
312 printw("%2d: %s", 1 + GameCnt / 2, ColorStr[player]);
313 ClearEoln();
317 void
318 Curses_ShowStage(void)
320 gotoXY(TAB, 19);
321 printw("Stage= %2d%c B= %2d W= %2d",
322 stage, flag.tsume?'T':' ', balance[black], balance[white]);
323 ClearEoln();
326 /****************************************
327 * End of trivial output routines.
328 ****************************************/
330 void
331 Curses_Initialize(void)
333 signal(SIGINT, Curses_Die);
334 signal(SIGQUIT, Curses_Die);
335 initscr();
336 crmode();
340 void
341 Curses_ExitShogi(void)
343 if (!nolist)
344 ListGame();
346 gotoXY(1, 24);
348 refresh();
349 nocrmode();
350 endwin();
352 exit(0);
356 void
357 Curses_Die(int sig)
359 char s[80];
361 signal(SIGINT, SIG_IGN);
362 signal(SIGQUIT, SIG_IGN);
364 Curses_ShowMessage("Abort? ");
365 FLUSH_SCANW("%s", s);
367 if (strcmp(s, "yes") == 0)
368 Curses_ExitShogi();
370 signal(SIGINT, Curses_Die);
371 signal(SIGQUIT, Curses_Die);
375 void
376 Curses_TerminateSearch(int sig)
378 signal(SIGINT, SIG_IGN);
379 signal(SIGQUIT, SIG_IGN);
381 if (!flag.timeout)
382 flag.musttimeout = true;
384 Curses_ShowMessage("Terminate Search");
385 flag.bothsides = false;
386 signal(SIGINT, Curses_Die);
387 signal(SIGQUIT, Curses_Die);
391 void
392 Curses_help(void)
394 Curses_ClearScreen();
395 printw("GNU Shogi %s command summary\n", PACKAGE_VERSION);
396 printw("-------------------------------"
397 "---------------------------------\n");
398 printw("7g7f move from 7g to 7f quit Exit Shogi\n");
399 printw("S6h move silver to 6h beep turn %s\n", (flag.beep) ? "OFF" : "ON");
400 printw("2d2c+ move to 2c and promote material turn %s\n", (flag.material) ? "OFF" : "ON");
401 printw("P*5e drop pawn to 5e easy turn %s\n", (flag.easy) ? "OFF" : "ON");
402 printw("tsume toggle tsume mode hash turn %s\n", (flag.hash) ? "OFF" : "ON");
403 printw("bd redraw board reverse board display\n");
404 printw("list game to shogi.lst book turn %s used %d of %d\n", (Book) ? "OFF" : "ON", bookcount, BOOKSIZE);
405 printw("undo undo last ply remove take back a move\n");
406 printw("edit edit board force toggle manual move mode\n");
407 printw("switch sides with computer both computer match\n");
408 printw("black computer plays black white computer plays white\n");
409 printw("depth set search depth clock set time control\n");
410 printw("post principle variation hint suggest a move\n", (flag.post) ? "OFF" : "ON");
411 printw("save game to file get game from file\n");
412 printw("random randomize play new start new game\n");
413 gotoXY(10, 20);
414 printw("Computer: %s", ColorStr[computer]);
415 gotoXY(10, 21);
416 printw("Opponent: %s", ColorStr[opponent]);
417 gotoXY(10, 22);
418 printw("Level: %ld", MaxResponseTime/100);
419 gotoXY(10, 23);
420 printw("Easy mode: %s", (flag.easy) ? "ON" : "OFF");
421 gotoXY(25, 23);
422 printw("Tsume: %s", (flag.tsume) ? "ON" : "OFF");
423 gotoXY(40, 20);
424 printw("Depth: %d", MaxSearchDepth);
425 gotoXY(40, 21);
426 printw("Random: %s", (dither) ? "ON" : "OFF");
427 gotoXY(40, 22);
428 printw("Transposition table: %s", (flag.hash) ? "ON" : "OFF");
429 gotoXY(40, 23);
430 printw("Hit <RET> to return: ");
431 gotoXY(10, 24);
432 printw("Time Control %s %d moves %d sec %d add %d depth\n", (TCflag) ? "ON" : "OFF",
433 TimeControl.moves[black],
434 TimeControl.clock[black] / 100,
435 OperatorTime, MaxSearchDepth);
437 refresh();
439 #ifdef BOGUS
440 fflush(stdin); /* what is this supposed to do?? */
441 #endif /* BOGUS */
443 getchar();
444 Curses_ClearScreen();
445 Curses_UpdateDisplay(0, 0, 1, 0);
449 static const short x0[2] = { 54, 2 };
450 static const short y0[2] = { 20, 4 };
454 * Set up a board position. Pieces are entered by typing the piece followed
455 * by the location. For example, N3f will place a knight on square 3f.
456 * P* will put a pawn to the captured pieces.
459 void
460 Curses_EditBoard(void)
462 short a, c, sq, i, found;
463 short r = 0;
464 char s[80];
466 flag.regularstart = true;
467 Book = BOOKFAIL;
468 Curses_ClearScreen();
469 Curses_UpdateDisplay(0, 0, 1, 0);
470 gotoXY(TAB, 11);
471 printw(". Exit to main\n");
472 gotoXY(TAB, 12);
473 printw("# Clear board\n");
474 gotoXY(TAB, 13);
475 printw("c Change sides\n");
476 gotoXY(TAB, 7);
477 printw("Enter piece & location: ");
478 a = black;
480 while(1)
482 gotoXY(TAB, 4);
483 printw("Editing: %s", ColorStr[a]);
484 gotoXY(TAB + 2, 8);
485 ClearEoln();
486 FLUSH_SCANW("%s", s);
487 found = 0;
488 ClearMessage();
490 if (s[0] == '.')
491 break;
493 if (s[0] == '#')
495 for (sq = 0; sq < NO_SQUARES; sq++)
497 board[sq] = no_piece;
498 color[sq] = neutral;
499 DrawPiece(sq);
502 ClearCaptured();
503 UpdateCatched();
504 continue;
507 if (s[0] == 'c') {
508 a = otherside[a];
509 continue;
512 if (s[1] == '*')
514 for (i = NO_PIECES; i > no_piece; i--)
516 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
518 Captured[a][unpromoted[i]]++;
519 UpdateCatched();
520 found = 1;
521 break;
524 if (!found)
525 AlwaysShowMessage("Invalid piece type '%c'", s[0]);
526 continue;
529 c = COL_NUM(s[1]);
530 r = ROW_NUM(s[2]);
532 if ((c < 0) || (c >= NO_COLS) || (r < 0) || (r >= NO_ROWS)) {
533 AlwaysShowMessage("Out-of-board '%c%c'", s[1], s[2]);
534 continue;
537 sq = locn(r, c);
539 for (i = NO_PIECES; i > no_piece; i--)
541 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
543 color[sq] = a;
544 if (s[3] == '+')
545 board[sq] = promoted[i];
546 else
547 board[sq] = unpromoted[i];
549 found = 1;
550 break;
554 if (!found)
555 AlwaysShowMessage("Invalid piece type '%c'", s[0]);
557 DrawPiece(sq);
560 for (sq = 0; sq < NO_SQUARES; sq++)
561 Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
563 GameCnt = 0;
564 Game50 = 1;
565 ZeroRPT();
566 Sdepth = 0;
567 InitializeStats();
568 Curses_ClearScreen();
569 Curses_UpdateDisplay(0, 0, 1, 0);
573 static void
574 UpdateCatched()
576 short side;
578 for (side = black; side <= white; side++)
580 short x, y, piece, cside, k;
582 cside = flag.reverse ? (side ^ 1) : side;
583 x = x0[cside];
584 y = y0[cside];
585 k = 0;
587 for (piece = pawn; piece <= king; piece++)
589 short n;
591 if ((n = Captured[side][piece]))
593 gotoXY(x, y);
594 printw("%i%c", n, pxx[piece]);
596 if (cside == black)
597 y--;
598 else
599 y++;
601 else
603 k++;
607 while (k)
609 k--;
610 gotoXY(x, y);
611 printw(" ");
613 if (cside == black)
614 y--;
615 else
616 y++;
620 refresh();
624 void
625 Curses_SearchStartStuff(short side)
627 short i;
629 signal(SIGINT, Curses_TerminateSearch);
630 signal(SIGQUIT, Curses_TerminateSearch);
632 for (i = 4; i < 14; i++) /* CHECKME */
634 gotoXY(TAB, i);
635 ClearEoln();
640 void
641 Curses_OutputMove(void)
644 Curses_UpdateDisplay(root->f, root->t, 0, (short) root->flags);
645 gotoXY(TAB, 16);
647 if (flag.illegal)
649 printw("Illegal position.");
650 return;
653 printw("My move is: %5s", mvstr[0]);
655 if (flag.beep)
656 putchar(7);
658 ClearEoln();
660 gotoXY(TAB, 18);
662 if (root->flags & draw)
663 printw("Drawn game!");
664 else if (root->score == -(SCORE_LIMIT + 999))
665 printw("Opponent mates!");
666 else if (root->score == SCORE_LIMIT + 998)
667 printw("Computer mates!");
668 #ifdef VERYBUGGY
669 else if (root->score < -SCORE_LIMIT)
670 printw("Opp: mate in %d!", SCORE_LIMIT + 999 + root->score - 1);
671 else if (root->score > SCORE_LIMIT)
672 printw("Comp: mate in %d!", SCORE_LIMIT + 998 - root->score - 1);
673 #endif /* VERYBUGGY */
675 ClearEoln();
677 if (flag.post)
679 short h, l, t;
681 h = TREE;
682 l = 0;
683 t = TREE >> 1;
685 while (l != t)
687 if (Tree[t].f || Tree[t].t)
688 l = t;
689 else
690 h = t;
692 t = (l + h) >> 1;
695 ShowNodeCnt(NodeCnt);
696 gotoXY(TAB, 23);
697 printw("Max Tree = %5d", t);
698 ClearEoln();
701 Curses_ShowSidetoMove();
705 void
706 Curses_UpdateClocks(void)
708 short m, s;
709 long dt;
711 if (TCflag)
713 m = (short) ((dt = (TimeControl.clock[player] - et)) / 6000);
714 s = (short) ((dt - 6000 * (long) m) / 100);
716 else
718 m = (short) ((dt = et) / 6000);
719 s = (short) (et - 6000 * (long) m) / 100;
722 if (m < 0)
723 m = 0;
725 if (s < 0)
726 s = 0;
728 if (player == black)
729 gotoXY(20, (flag.reverse) ? 2 : (5 + 2*NO_ROWS));
730 else
731 gotoXY(20, (flag.reverse) ? (5 + 2*NO_ROWS) : 2);
733 /* printw("%d:%02d %ld ", m, s, dt); */
734 printw("%d:%02d ", m, s);
736 if (flag.post)
737 ShowNodeCnt(NodeCnt);
739 refresh();
743 static void
744 DrawPiece(short sq)
746 char y;
747 char piece, l, r, p;
749 if (color[sq] == neutral)
751 l = r = ' ';
753 else if (flag.reverse ^ (color[sq] == black))
755 l = '/';
756 r = '\\';
758 else
760 l = '\\', r = '/';
763 piece = board[sq];
765 if (is_promoted[(int)piece])
767 p = '+';
768 y = pxx[unpromoted[(int)piece]];
770 else
772 p = ' ';
773 y = pxx[(int)piece];
776 gotoXY(MARGIN + 3 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
777 printw("%c%c%c%c", l, p, y, r);
782 * Curses_ShowPostnValue(): must have called ExaminePosition() first
784 void
785 Curses_ShowPostnValue(short sq)
787 short score;
789 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq))); /* CHECKME */
790 score = ScorePosition(color[sq]);
792 if (color[sq] != neutral)
793 #if defined SAVE_SVALUE
795 printw("??? ");
797 #else
799 printw("%3d ", svalue[sq]);
801 #endif
802 else
804 printw(" ");
809 void
810 Curses_ShowPostnValues(void)
812 short sq, score;
814 ExaminePosition(opponent);
816 for (sq = 0; sq < NO_SQUARES; sq++)
817 Curses_ShowPostnValue(sq);
819 score = ScorePosition(opponent);
820 gotoXY(TAB, 5);
821 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
822 mtl[computer], pscore[computer], GameType[computer],
823 mtl[opponent], pscore[opponent], GameType[opponent]);
825 ClearEoln();
829 void
830 Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
832 short i, sq, z;
833 int j;
835 if (redraw)
837 ShowHeader();
838 ShowPlayers();
840 i = 2;
841 gotoXY(MARGIN, ++i);
843 printw(" +");
844 for (j=0; j<NO_COLS; j++)
845 printw("----+");
847 while (i <= 1 + 2*NO_ROWS)
849 gotoXY(MARGIN, ++i);
851 if (flag.reverse)
852 z = (i / 2) - 1;
853 else
854 z = NO_ROWS + 2 - ((i + 1) / 2);
856 printw("%c |", ROW_NAME(z+1));
857 for (j=0; j<NO_COLS; j++)
858 printw(" |");
860 gotoXY(MARGIN, ++i);
862 if (i < 2 + 2*NO_ROWS)
864 printw(" +");
865 for (j=0; j<NO_COLS; j++)
866 printw("----+");
870 printw(" +");
871 for (j=0; j<NO_COLS; j++)
872 printw("----+");
874 gotoXY(MARGIN, 4 + 2*NO_ROWS);
875 printw(" ");
876 #ifndef MINISHOGI
877 if (flag.reverse)
878 printw(" 1 2 3 4 5 6 7 8 9");
879 else
880 printw(" 9 8 7 6 5 4 3 2 1");
881 #else
882 if (flag.reverse)
883 printw(" 1 2 3 4 5");
884 else
885 printw(" 5 4 3 2 1");
886 #endif
888 for (sq = 0; sq < NO_SQUARES; sq++)
889 DrawPiece(sq);
891 else /* not redraw */
893 if (f < NO_SQUARES)
894 DrawPiece(f);
896 DrawPiece(t & 0x7f);
899 if ((isspec & capture) || (isspec & dropmask) || redraw)
901 short side;
903 for (side = black; side <= white; side++)
905 short x, y, piece, cside, k;
906 cside = flag.reverse ? (side ^ 1) : side;
907 x = x0[cside];
908 y = y0[cside];
909 k = 0;
911 for (piece = pawn; piece <= king; piece++)
913 short n;
915 if ((n = Captured[side][piece]))
917 gotoXY(x, y);
918 printw("%i%c", n, pxx[piece]);
920 if (cside == black) y--; else y++;
922 else
924 k++;
928 while (k)
930 k--;
931 gotoXY(x, y);
932 printw(" ");
934 if (cside == black)
935 y--;
936 else
937 y++;
942 refresh();
946 void
947 Curses_ChangeAlphaWindow(void)
949 Curses_ShowMessage("WAwindow = ");
950 FLUSH_SCANW("%hd", &WAwindow);
951 Curses_ShowMessage("BAwindow = ");
952 FLUSH_SCANW("%hd", &BAwindow);
956 void
957 Curses_ChangeBetaWindow(void)
959 Curses_ShowMessage("WBwindow = ");
960 FLUSH_SCANW("%hd", &WBwindow);
961 Curses_ShowMessage("BBwindow = ");
962 FLUSH_SCANW("%hd", &BBwindow);
966 void
967 Curses_GiveHint(void)
969 char s[40];
971 if (hint)
973 algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
974 strcpy(s, "try ");
975 strcat(s, mvstr[0]);
976 Curses_ShowMessage(s);
978 else
980 Curses_ShowMessage("I have no idea.\n");
985 void
986 Curses_ChangeSearchDepth(void)
988 Curses_ShowMessage("depth = ");
989 FLUSH_SCANW("%hd", &MaxSearchDepth);
990 TCflag = !(MaxSearchDepth > 0);
994 void
995 Curses_ChangeHashDepth(void)
997 Curses_ShowMessage("hashdepth = ");
998 FLUSH_SCANW("%hd", &HashDepth);
999 Curses_ShowMessage("MoveLimit = ");
1000 FLUSH_SCANW("%hd", &HashMoveLimit);
1004 void
1005 Curses_SetContempt(void)
1007 Curses_ShowMessage("contempt = ");
1008 FLUSH_SCANW("%hd", &contempt);
1012 void
1013 Curses_ChangeXwindow(void)
1015 Curses_ShowMessage("xwndw= ");
1016 FLUSH_SCANW("%hd", &xwndw);
1020 void
1021 Curses_SelectLevel(char *sx)
1023 int item;
1025 Curses_ClearScreen();
1026 gotoXY(32, 2);
1027 printw("GNU Shogi %s", PACKAGE_VERSION);
1028 gotoXY(20, 4);
1029 printw(" 1. 40 moves in 5 minutes");
1030 gotoXY(20, 5);
1031 printw(" 2. 40 moves in 15 minutes");
1032 gotoXY(20, 6);
1033 printw(" 3. 40 moves in 30 minutes");
1034 gotoXY(20, 7);
1035 printw(" 4. all moves in 15 minutes");
1036 gotoXY(20, 8);
1037 printw(" 5. all moves in 30 minutes");
1038 gotoXY(20, 9);
1039 printw(" 6. all moves in 15 minutes, 30 seconds fischer clock");
1040 gotoXY(20, 10);
1041 printw(" 7. all moves in 30 minutes, 30 seconds fischer clock");
1042 gotoXY(20, 11);
1043 printw(" 8. 1 move in 1 minute");
1044 gotoXY(20, 12);
1045 printw(" 9. 1 move in 15 minutes");
1046 gotoXY(20, 13);
1047 printw("10. 1 move in 30 minutes");
1049 OperatorTime = 0;
1050 TCmoves = 40;
1051 TCminutes = 5;
1052 TCseconds = 0;
1054 gotoXY(20, 17);
1055 printw("Enter Level: ");
1056 refresh();
1057 FLUSH_SCANW("%d", &item);
1059 switch(item)
1061 case 1:
1062 TCmoves = 40;
1063 TCminutes = 5;
1064 break;
1066 case 2:
1067 TCmoves = 40;
1068 TCminutes = 15;
1069 break;
1071 case 3:
1072 TCmoves = 40;
1073 TCminutes = 30;
1074 break;
1076 case 4:
1077 TCmoves = 80;
1078 TCminutes = 15;
1079 flag.gamein = true;
1080 break;
1082 case 5:
1083 TCmoves = 80;
1084 TCminutes = 30;
1085 flag.gamein = true;
1086 break;
1088 case 6:
1089 TCmoves = 80;
1090 TCminutes = 15;
1091 TCadd = 3000;
1092 flag.gamein = true;
1093 break;
1095 case 7:
1096 TCmoves = 80;
1097 TCminutes = 30;
1098 TCadd = 3000;
1099 break;
1101 case 8:
1102 TCmoves = 1;
1103 TCminutes = 1;
1104 flag.onemove = true;
1105 break;
1107 case 9:
1108 TCmoves = 1;
1109 TCminutes = 15;
1110 flag.onemove = true;
1111 break;
1113 case 10:
1114 TCmoves = 1;
1115 TCminutes = 30;
1116 flag.onemove = true;
1117 break;
1120 TCflag = (TCmoves > 0);
1122 TimeControl.clock[black] = TimeControl.clock[white] = 0;
1124 SetTimeControl();
1125 Curses_ClearScreen();
1126 Curses_UpdateDisplay(0, 0, 1, 0);
1130 void
1131 Curses_DoDebug(void)
1133 short c, p, sq, tp, tc, tsq, score;
1134 char s[40];
1136 ExaminePosition(opponent);
1137 Curses_ShowMessage("Enter piece: ");
1138 FLUSH_SCANW("%s", s);
1139 c = neutral;
1141 if ((s[0] == 'b') || (s[0] == 'B'))
1142 c = black;
1144 if ((s[0] == 'w') || (s[0] == 'W'))
1145 c = white;
1147 for (p = king; p > no_piece; p--)
1149 if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
1150 break;
1153 for (sq = 0; sq < NO_SQUARES; sq++)
1155 tp = board[sq];
1156 tc = color[sq];
1157 board[sq] = p;
1158 color[sq] = c;
1159 tsq = PieceList[c][1];
1160 PieceList[c][1] = sq;
1161 Curses_ShowPostnValue(sq);
1162 PieceList[c][1] = tsq;
1163 board[sq] = tp;
1164 color[sq] = tc;
1167 score = ScorePosition(opponent);
1168 gotoXY(TAB, 5);
1169 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
1170 mtl[computer], pscore[computer], GameType[computer],
1171 mtl[opponent], pscore[opponent], GameType[opponent]);
1173 ClearEoln();
1177 void
1178 Curses_DoTable(short table[NO_SQUARES])
1180 short sq;
1181 ExaminePosition(opponent);
1183 for (sq = 0; sq < NO_SQUARES; sq++)
1185 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));
1186 printw("%3d ", table[sq]);
1191 void
1192 Curses_PollForInput(void)
1194 int i;
1195 int nchar;
1197 if ((i = ioctl((int) 0, FIONREAD, &nchar)))
1199 perror("FIONREAD");
1200 fprintf(stderr,
1201 "You probably have a non-ANSI <ioctl.h>; "
1202 "see README. %d %d %x\n",
1203 i, errno, FIONREAD);
1204 exit(1);
1207 if (nchar)
1209 if (!flag.timeout)
1210 flag.back = true;
1212 flag.bothsides = false;
1217 void
1218 Curses_SetupBoard(void)
1220 Curses_ShowMessage("'setup' command is not supported in Cursesmode");