EditBoard: simplify loop logic by ending iterations early.
[gnushogi.git] / gnushogi / cursesdsp.c
blob127f6b41e426b6acd376da10e94a5fcb508556ff
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 TAB (58)
69 #define VIR_C(s) ((flag.reverse) ? (NO_COLS - 1 - column(s)) : column(s))
70 #define VIR_R(s) ((flag.reverse) ? (NO_ROWS - 1 - row(s)) : row(s))
72 unsigned short MV[MAXDEPTH];
73 int MSCORE;
74 char *DRAW;
76 /* Forward declarations. */
77 /* FIXME: change this name, puh-leeze! */
79 static void UpdateCatched(void);
80 static void DrawPiece(short sq);
81 static void ShowScore(short score);
83 /****************************************
84 * Trivial output functions.
85 ****************************************/
87 static void
88 ClearEoln(void)
90 clrtoeol();
91 refresh();
95 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();
118 void
119 Curses_ShowCurrentMove(short pnt, short f, short t)
121 algbr(f, t, false);
122 gotoXY(TAB, 7);
123 printw("(%2d) %5s ", pnt, mvstr[0]);
127 void
128 Curses_ShowDepth(char ch)
130 gotoXY(TAB, 4);
131 printw("Depth= %d%c ", Sdepth, ch);
132 ClearEoln();
136 void
137 Curses_ShowGameType(void)
139 if (flag.post)
141 gotoXY(TAB, 20);
142 printw("%c vs. %c", GameType[black], GameType[white]);
147 void
148 ShowHeader(void)
150 gotoXY(TAB, 2);
151 printw("GNU Shogi %s", PACKAGE_VERSION);
155 void
156 Curses_ShowLine(unsigned short *bstline)
161 void
162 Curses_ShowMessage(char *s)
164 gotoXY(TAB, 6);
165 printw("%s", s);
166 ClearEoln();
170 void
171 Curses_AlwaysShowMessage(const char *format, va_list ap)
173 static char buffer[60];
174 vsnprintf(buffer, sizeof(buffer), format, ap);
175 Curses_ShowMessage(buffer);
179 void
180 Curses_Printf(const char *format, va_list ap)
182 static char buffer[60];
183 vsnprintf(buffer, sizeof(buffer), format, ap);
184 printw("%s", buffer);
188 void
189 Curses_doRequestInputString(const char* fmt, char* buffer)
191 FLUSH_SCANW(fmt, buffer);
196 Curses_GetString(char* sx)
198 fflush(stdout);
199 return (getstr(sx) == ERR);
203 void
204 Curses_ShowNodeCnt(long NodeCnt)
206 gotoXY(TAB, 22);
207 /* printw("Nodes = %8ld, Nodes/Sec = %5ld", NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0); */
208 printw("n = %ld n/s = %ld",
209 NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0);
210 ClearEoln();
214 void
215 Curses_ShowPatternCount(short side, short n)
217 if (flag.post)
219 gotoXY(TAB + 10 + 3 * side, 20); /* CHECKME */
221 if (n >= 0)
222 printw("%3d", n);
223 else
224 printw(" ");
229 static void
230 ShowPlayers(void)
232 gotoXY(5, ((flag.reverse) ? (5 + 2*NO_ROWS) : 2));
233 printw("%s", (computer == white) ? "Computer" : "Human ");
234 gotoXY(5, ((flag.reverse) ? 2 : (5 + 2*NO_ROWS)));
235 printw("%s", (computer == black) ? "Computer" : "Human ");
239 void
240 Curses_ShowPrompt(void)
242 Curses_ShowSidetoMove();
243 gotoXY(TAB, 17);
244 printw("Your move is? ");
245 ClearEoln();
249 void
250 Curses_ShowResponseTime(void)
252 if (flag.post)
254 short TCC = TCcount;
255 gotoXY(TAB, 21);
256 printw("%ld, %d, %ld, %ld, %ld, %d",
257 ResponseTime, TCC, TCleft, ExtraTime, et, flag.timeout);
258 ClearEoln();
263 void
264 Curses_ShowResults(short score, unsigned short *bstline, char ch)
266 unsigned char d, ply;
268 if (flag.post)
270 Curses_ShowDepth(ch);
271 ShowScore(score);
272 d = 7;
274 for (ply = 1; bstline[ply] > 0; ply++)
276 if (ply % 2 == 1)
278 gotoXY(TAB, ++d);
279 ClearEoln();
282 algbr((short) bstline[ply] >> 8,
283 (short) bstline[ply] & 0xFF, false);
284 printw("%5s ", mvstr[0]);
287 ClearEoln();
289 while (d < 13)
291 gotoXY(TAB, ++d);
292 ClearEoln();
298 static void
299 ShowScore(short score)
301 gotoXY(TAB, 5);
302 printw("Score= %d", score);
303 ClearEoln();
307 void
308 Curses_ShowSidetoMove(void)
310 gotoXY(TAB, 14);
311 printw("%2d: %s", 1 + GameCnt / 2, ColorStr[player]);
312 ClearEoln();
316 void
317 Curses_ShowStage(void)
319 gotoXY(TAB, 19);
320 printw("Stage= %2d%c B= %2d W= %2d",
321 stage, flag.tsume?'T':' ', balance[black], balance[white]);
322 ClearEoln();
325 /****************************************
326 * End of trivial output routines.
327 ****************************************/
329 void
330 Curses_Initialize(void)
332 signal(SIGINT, Curses_Die);
333 signal(SIGQUIT, Curses_Die);
334 initscr();
335 crmode();
339 void
340 Curses_ExitShogi(void)
342 if (!nolist)
343 ListGame();
345 gotoXY(1, 24);
347 refresh();
348 nocrmode();
349 endwin();
351 exit(0);
355 void
356 Curses_Die(int sig)
358 char s[80];
360 signal(SIGINT, SIG_IGN);
361 signal(SIGQUIT, SIG_IGN);
363 Curses_ShowMessage("Abort? ");
364 FLUSH_SCANW("%s", s);
366 if (strcmp(s, "yes") == 0)
367 Curses_ExitShogi();
369 signal(SIGINT, Curses_Die);
370 signal(SIGQUIT, Curses_Die);
374 void
375 Curses_TerminateSearch(int sig)
377 signal(SIGINT, SIG_IGN);
378 signal(SIGQUIT, SIG_IGN);
380 if (!flag.timeout)
381 flag.musttimeout = true;
383 Curses_ShowMessage("Terminate Search");
384 flag.bothsides = false;
385 signal(SIGINT, Curses_Die);
386 signal(SIGQUIT, Curses_Die);
390 void
391 Curses_help(void)
393 Curses_ClearScreen();
394 printw("GNU Shogi %s command summary\n", PACKAGE_VERSION);
395 printw("-------------------------------"
396 "---------------------------------\n");
397 printw("7g7f move from 7g to 7f quit Exit Shogi\n");
398 printw("S6h move silver to 6h beep turn %s\n", (flag.beep) ? "OFF" : "ON");
399 printw("2d2c+ move to 2c and promote material turn %s\n", (flag.material) ? "OFF" : "ON");
400 printw("P*5e drop pawn to 5e easy turn %s\n", (flag.easy) ? "OFF" : "ON");
401 printw("tsume toggle tsume mode hash turn %s\n", (flag.hash) ? "OFF" : "ON");
402 printw("bd redraw board reverse board display\n");
403 printw("list game to shogi.lst book turn %s used %d of %d\n", (Book) ? "OFF" : "ON", bookcount, BOOKSIZE);
404 printw("undo undo last ply remove take back a move\n");
405 printw("edit edit board force toggle manual move mode\n");
406 printw("switch sides with computer both computer match\n");
407 printw("black computer plays black white computer plays white\n");
408 printw("depth set search depth clock set time control\n");
409 printw("post principle variation hint suggest a move\n", (flag.post) ? "OFF" : "ON");
410 printw("save game to file get game from file\n");
411 printw("random randomize play new start new game\n");
412 gotoXY(10, 20);
413 printw("Computer: %s", ColorStr[computer]);
414 gotoXY(10, 21);
415 printw("Opponent: %s", ColorStr[opponent]);
416 gotoXY(10, 22);
417 printw("Level: %ld", MaxResponseTime/100);
418 gotoXY(10, 23);
419 printw("Easy mode: %s", (flag.easy) ? "ON" : "OFF");
420 gotoXY(25, 23);
421 printw("Tsume: %s", (flag.tsume) ? "ON" : "OFF");
422 gotoXY(40, 20);
423 printw("Depth: %d", MaxSearchDepth);
424 gotoXY(40, 21);
425 printw("Random: %s", (dither) ? "ON" : "OFF");
426 gotoXY(40, 22);
427 printw("Transposition table: %s", (flag.hash) ? "ON" : "OFF");
428 gotoXY(40, 23);
429 printw("Hit <RET> to return: ");
430 gotoXY(10, 24);
431 printw("Time Control %s %d moves %d sec %d add %d depth\n", (TCflag) ? "ON" : "OFF",
432 TimeControl.moves[black],
433 TimeControl.clock[black] / 100,
434 OperatorTime, MaxSearchDepth);
436 refresh();
438 #ifdef BOGUS
439 fflush(stdin); /* what is this supposed to do?? */
440 #endif /* BOGUS */
442 getchar();
443 Curses_ClearScreen();
444 Curses_UpdateDisplay(0, 0, 1, 0);
448 static const short x0[2] = { 54, 2 };
449 static const short y0[2] = { 20, 4 };
453 * Set up a board position. Pieces are entered by typing the piece followed
454 * by the location. For example, N3f will place a knight on square 3f.
455 * P* will put a pawn to the captured pieces.
458 void
459 Curses_EditBoard(void)
461 short a, c, sq, i, found;
462 short r = 0;
463 char s[80];
465 flag.regularstart = true;
466 Book = BOOKFAIL;
467 Curses_ClearScreen();
468 Curses_UpdateDisplay(0, 0, 1, 0);
469 gotoXY(TAB, 3);
470 printw(". Exit to main\n");
471 gotoXY(TAB, 4);
472 printw("# Clear board\n");
473 gotoXY(TAB, 5);
474 printw("c Change sides\n");
475 gotoXY(TAB, 7);
476 printw("Enter piece & location: ");
477 a = black;
479 while(1)
481 gotoXY(TAB, 6);
482 printw("Editing: %s", ColorStr[a]);
483 gotoXY(TAB + 24, 7);
484 ClearEoln();
485 FLUSH_SCANW("%s", s);
486 found = 0;
488 if (s[0] == '.')
489 break;
491 if (s[0] == '#')
493 for (sq = 0; sq < NO_SQUARES; sq++)
495 board[sq] = no_piece;
496 color[sq] = neutral;
497 DrawPiece(sq);
500 ClearCaptured();
501 UpdateCatched();
502 continue;
505 if (s[0] == 'c') {
506 a = otherside[a];
507 continue;
510 if (s[1] == '*')
512 for (i = NO_PIECES; i > no_piece; i--)
514 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
516 Captured[a][unpromoted[i]]++;
517 UpdateCatched();
518 found = 1;
519 break;
523 continue;
526 c = COL_NUM(s[1]);
527 r = ROW_NUM(s[2]);
529 if ((c < 0) || (c >= NO_COLS) || (r < 0) || (r >= NO_ROWS))
530 continue;
532 sq = locn(r, c);
533 color[sq] = a;
534 board[sq] = no_piece;
536 for (i = NO_PIECES; i > no_piece; i--)
538 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
540 if (s[3] == '+')
541 board[sq] = promoted[i];
542 else
543 board[sq] = unpromoted[i];
545 found = 1;
546 break;
551 if (found == 0)
552 color[sq] = neutral;
554 DrawPiece(sq);
557 for (sq = 0; sq < NO_SQUARES; sq++)
558 Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
560 GameCnt = 0;
561 Game50 = 1;
562 ZeroRPT();
563 Sdepth = 0;
564 InitializeStats();
565 Curses_ClearScreen();
566 Curses_UpdateDisplay(0, 0, 1, 0);
570 static void
571 UpdateCatched()
573 short side;
575 for (side = black; side <= white; side++)
577 short x, y, piece, cside, k;
579 cside = flag.reverse ? (side ^ 1) : side;
580 x = x0[cside];
581 y = y0[cside];
582 k = 0;
584 for (piece = pawn; piece <= king; piece++)
586 short n;
588 if ((n = Captured[side][piece]))
590 gotoXY(x, y);
591 printw("%i%c", n, pxx[piece]);
593 if (cside == black)
594 y--;
595 else
596 y++;
598 else
600 k++;
604 while (k)
606 k--;
607 gotoXY(x, y);
608 printw(" ");
610 if (cside == black)
611 y--;
612 else
613 y++;
617 refresh();
621 void
622 Curses_SearchStartStuff(short side)
624 short i;
626 signal(SIGINT, Curses_TerminateSearch);
627 signal(SIGQUIT, Curses_TerminateSearch);
629 for (i = 4; i < 14; i++) /* CHECKME */
631 gotoXY(TAB, i);
632 ClearEoln();
637 void
638 Curses_OutputMove(void)
641 Curses_UpdateDisplay(root->f, root->t, 0, (short) root->flags);
642 gotoXY(TAB, 16);
644 if (flag.illegal)
646 printw("Illegal position.");
647 return;
650 printw("My move is: %5s", mvstr[0]);
652 if (flag.beep)
653 putchar(7);
655 ClearEoln();
657 gotoXY(TAB, 18);
659 if (root->flags & draw)
660 printw("Drawn game!");
661 else if (root->score == -(SCORE_LIMIT + 999))
662 printw("Opponent mates!");
663 else if (root->score == SCORE_LIMIT + 998)
664 printw("Computer mates!");
665 #ifdef VERYBUGGY
666 else if (root->score < -SCORE_LIMIT)
667 printw("Opp: mate in %d!", SCORE_LIMIT + 999 + root->score - 1);
668 else if (root->score > SCORE_LIMIT)
669 printw("Comp: mate in %d!", SCORE_LIMIT + 998 - root->score - 1);
670 #endif /* VERYBUGGY */
672 ClearEoln();
674 if (flag.post)
676 short h, l, t;
678 h = TREE;
679 l = 0;
680 t = TREE >> 1;
682 while (l != t)
684 if (Tree[t].f || Tree[t].t)
685 l = t;
686 else
687 h = t;
689 t = (l + h) >> 1;
692 ShowNodeCnt(NodeCnt);
693 gotoXY(TAB, 23);
694 printw("Max Tree = %5d", t);
695 ClearEoln();
698 Curses_ShowSidetoMove();
702 void
703 Curses_UpdateClocks(void)
705 short m, s;
706 long dt;
708 if (TCflag)
710 m = (short) ((dt = (TimeControl.clock[player] - et)) / 6000);
711 s = (short) ((dt - 6000 * (long) m) / 100);
713 else
715 m = (short) ((dt = et) / 6000);
716 s = (short) (et - 6000 * (long) m) / 100;
719 if (m < 0)
720 m = 0;
722 if (s < 0)
723 s = 0;
725 if (player == black)
726 gotoXY(20, (flag.reverse) ? 2 : 23);
727 else
728 gotoXY(20, (flag.reverse) ? 23 : 2);
730 /* printw("%d:%02d %ld ", m, s, dt); */
731 printw("%d:%02d ", m, s);
733 if (flag.post)
734 ShowNodeCnt(NodeCnt);
736 refresh();
740 static void
741 DrawPiece(short sq)
743 char y;
744 char piece, l, r, p;
746 if (color[sq] == neutral)
748 l = r = ' ';
750 else if (flag.reverse ^ (color[sq] == black))
752 l = '/';
753 r = '\\';
755 else
757 l = '\\', r = '/';
760 piece = board[sq];
762 if (is_promoted[(int)piece])
764 p = '+';
765 y = pxx[unpromoted[(int)piece]];
767 else
769 p = ' ';
770 y = pxx[(int)piece];
773 gotoXY(8 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
774 printw("%c%c%c%c", l, p, y, r);
779 * Curses_ShowPostnValue(): must have called ExaminePosition() first
781 void
782 Curses_ShowPostnValue(short sq)
784 short score;
786 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq))); /* CHECKME */
787 score = ScorePosition(color[sq]);
789 if (color[sq] != neutral)
790 #if defined SAVE_SVALUE
792 printw("??? ");
794 #else
796 printw("%3d ", svalue[sq]);
798 #endif
799 else
801 printw(" ");
806 void
807 Curses_ShowPostnValues(void)
809 short sq, score;
811 ExaminePosition(opponent);
813 for (sq = 0; sq < NO_SQUARES; sq++)
814 Curses_ShowPostnValue(sq);
816 score = ScorePosition(opponent);
817 gotoXY(TAB, 5);
818 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
819 mtl[computer], pscore[computer], GameType[computer],
820 mtl[opponent], pscore[opponent], GameType[opponent]);
822 ClearEoln();
826 void
827 Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
829 short i, sq, z;
830 int j;
832 if (redraw)
834 ShowHeader();
835 ShowPlayers();
837 i = 2;
838 gotoXY(3, ++i);
840 printw(" +");
841 for (j=0; j<NO_COLS; j++)
842 printw("----+");
844 while (i <= 1 + 2*NO_ROWS)
846 gotoXY(1, ++i);
848 if (flag.reverse)
849 z = (i / 2) - 1;
850 else
851 z = NO_ROWS + 2 - ((i + 1) / 2);
853 printw(" %c |", ROW_NAME(z+1));
854 for (j=0; j<NO_COLS; j++)
855 printw(" |");
857 gotoXY(3, ++i);
859 if (i < 2 + 2*NO_ROWS)
861 printw(" +");
862 for (j=0; j<NO_COLS; j++)
863 printw("----+");
867 printw(" +");
868 for (j=0; j<NO_COLS; j++)
869 printw("----+");
871 gotoXY(3, 4 + 2*NO_ROWS);
872 printw(" ");
874 #ifndef MINISHOGI
875 if (flag.reverse)
876 printw(" 1 2 3 4 5 6 7 8 9");
877 else
878 printw(" 9 8 7 6 5 4 3 2 1");
879 #else
880 if (flag.reverse)
881 printw(" 1 2 3 4 5");
882 else
883 printw(" 1 2 3 4 5");
884 #endif
886 for (sq = 0; sq < NO_SQUARES; sq++)
887 DrawPiece(sq);
889 else /* not redraw */
891 if (f < NO_SQUARES)
892 DrawPiece(f);
894 DrawPiece(t & 0x7f);
897 if ((isspec & capture) || (isspec & dropmask) || redraw)
899 short side;
901 for (side = black; side <= white; side++)
903 short x, y, piece, cside, k;
904 cside = flag.reverse ? (side ^ 1) : side;
905 x = x0[cside];
906 y = y0[cside];
907 k = 0;
909 for (piece = pawn; piece <= king; piece++)
911 short n;
913 if ((n = Captured[side][piece]))
915 gotoXY(x, y);
916 printw("%i%c", n, pxx[piece]);
918 if (cside == black) y--; else y++;
920 else
922 k++;
926 while (k)
928 k--;
929 gotoXY(x, y);
930 printw(" ");
932 if (cside == black)
933 y--;
934 else
935 y++;
940 refresh();
944 void
945 Curses_ChangeAlphaWindow(void)
947 Curses_ShowMessage("WAwindow = ");
948 FLUSH_SCANW("%hd", &WAwindow);
949 Curses_ShowMessage("BAwindow = ");
950 FLUSH_SCANW("%hd", &BAwindow);
954 void
955 Curses_ChangeBetaWindow(void)
957 Curses_ShowMessage("WBwindow = ");
958 FLUSH_SCANW("%hd", &WBwindow);
959 Curses_ShowMessage("BBwindow = ");
960 FLUSH_SCANW("%hd", &BBwindow);
964 void
965 Curses_GiveHint(void)
967 char s[40];
969 if (hint)
971 algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
972 strcpy(s, "try ");
973 strcat(s, mvstr[0]);
974 Curses_ShowMessage(s);
976 else
978 Curses_ShowMessage("I have no idea.\n");
983 void
984 Curses_ChangeSearchDepth(void)
986 Curses_ShowMessage("depth = ");
987 FLUSH_SCANW("%hd", &MaxSearchDepth);
988 TCflag = !(MaxSearchDepth > 0);
992 void
993 Curses_ChangeHashDepth(void)
995 Curses_ShowMessage("hashdepth = ");
996 FLUSH_SCANW("%hd", &HashDepth);
997 Curses_ShowMessage("MoveLimit = ");
998 FLUSH_SCANW("%hd", &HashMoveLimit);
1002 void
1003 Curses_SetContempt(void)
1005 Curses_ShowMessage("contempt = ");
1006 FLUSH_SCANW("%hd", &contempt);
1010 void
1011 Curses_ChangeXwindow(void)
1013 Curses_ShowMessage("xwndw= ");
1014 FLUSH_SCANW("%hd", &xwndw);
1018 void
1019 Curses_SelectLevel(char *sx)
1021 int item;
1023 Curses_ClearScreen();
1024 gotoXY(32, 2);
1025 printw("GNU Shogi %s", PACKAGE_VERSION);
1026 gotoXY(20, 4);
1027 printw(" 1. 40 moves in 5 minutes");
1028 gotoXY(20, 5);
1029 printw(" 2. 40 moves in 15 minutes");
1030 gotoXY(20, 6);
1031 printw(" 3. 40 moves in 30 minutes");
1032 gotoXY(20, 7);
1033 printw(" 4. all moves in 15 minutes");
1034 gotoXY(20, 8);
1035 printw(" 5. all moves in 30 minutes");
1036 gotoXY(20, 9);
1037 printw(" 6. all moves in 15 minutes, 30 seconds fischer clock");
1038 gotoXY(20, 10);
1039 printw(" 7. all moves in 30 minutes, 30 seconds fischer clock");
1040 gotoXY(20, 11);
1041 printw(" 8. 1 move in 1 minute");
1042 gotoXY(20, 12);
1043 printw(" 9. 1 move in 15 minutes");
1044 gotoXY(20, 13);
1045 printw("10. 1 move in 30 minutes");
1047 OperatorTime = 0;
1048 TCmoves = 40;
1049 TCminutes = 5;
1050 TCseconds = 0;
1052 gotoXY(20, 17);
1053 printw("Enter Level: ");
1054 refresh();
1055 FLUSH_SCANW("%d", &item);
1057 switch(item)
1059 case 1:
1060 TCmoves = 40;
1061 TCminutes = 5;
1062 break;
1064 case 2:
1065 TCmoves = 40;
1066 TCminutes = 15;
1067 break;
1069 case 3:
1070 TCmoves = 40;
1071 TCminutes = 30;
1072 break;
1074 case 4:
1075 TCmoves = 80;
1076 TCminutes = 15;
1077 flag.gamein = true;
1078 break;
1080 case 5:
1081 TCmoves = 80;
1082 TCminutes = 30;
1083 flag.gamein = true;
1084 break;
1086 case 6:
1087 TCmoves = 80;
1088 TCminutes = 15;
1089 TCadd = 3000;
1090 flag.gamein = true;
1091 break;
1093 case 7:
1094 TCmoves = 80;
1095 TCminutes = 30;
1096 TCadd = 3000;
1097 break;
1099 case 8:
1100 TCmoves = 1;
1101 TCminutes = 1;
1102 flag.onemove = true;
1103 break;
1105 case 9:
1106 TCmoves = 1;
1107 TCminutes = 15;
1108 flag.onemove = true;
1109 break;
1111 case 10:
1112 TCmoves = 1;
1113 TCminutes = 30;
1114 flag.onemove = true;
1115 break;
1118 TCflag = (TCmoves > 0);
1120 TimeControl.clock[black] = TimeControl.clock[white] = 0;
1122 SetTimeControl();
1123 Curses_ClearScreen();
1124 Curses_UpdateDisplay(0, 0, 1, 0);
1128 void
1129 Curses_DoDebug(void)
1131 short c, p, sq, tp, tc, tsq, score;
1132 char s[40];
1134 ExaminePosition(opponent);
1135 Curses_ShowMessage("Enter piece: ");
1136 FLUSH_SCANW("%s", s);
1137 c = neutral;
1139 if ((s[0] == 'b') || (s[0] == 'B'))
1140 c = black;
1142 if ((s[0] == 'w') || (s[0] == 'W'))
1143 c = white;
1145 for (p = king; p > no_piece; p--)
1147 if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
1148 break;
1151 for (sq = 0; sq < NO_SQUARES; sq++)
1153 tp = board[sq];
1154 tc = color[sq];
1155 board[sq] = p;
1156 color[sq] = c;
1157 tsq = PieceList[c][1];
1158 PieceList[c][1] = sq;
1159 Curses_ShowPostnValue(sq);
1160 PieceList[c][1] = tsq;
1161 board[sq] = tp;
1162 color[sq] = tc;
1165 score = ScorePosition(opponent);
1166 gotoXY(TAB, 5);
1167 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
1168 mtl[computer], pscore[computer], GameType[computer],
1169 mtl[opponent], pscore[opponent], GameType[opponent]);
1171 ClearEoln();
1175 void
1176 Curses_DoTable(short table[NO_SQUARES])
1178 short sq;
1179 ExaminePosition(opponent);
1181 for (sq = 0; sq < NO_SQUARES; sq++)
1183 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));
1184 printw("%3d ", table[sq]);
1189 void
1190 Curses_PollForInput(void)
1192 int i;
1193 int nchar;
1195 if ((i = ioctl((int) 0, FIONREAD, &nchar)))
1197 perror("FIONREAD");
1198 fprintf(stderr,
1199 "You probably have a non-ANSI <ioctl.h>; "
1200 "see README. %d %d %x\n",
1201 i, errno, FIONREAD);
1202 exit(1);
1205 if (nchar)
1207 if (!flag.timeout)
1208 flag.back = true;
1210 flag.bothsides = false;
1215 void
1216 Curses_SetupBoard(void)
1218 Curses_ShowMessage("'setup' command is not supported in Cursesmode");