Update maintainership info in AUTHORS.
[gnushogi.git] / gnushogi / cursesdsp.c
blobee492b26556972117b7143837bdef55fad7e681b
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;
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;
481 gotoXY(TAB, 6);
482 printw("Editing: %s", ColorStr[a]);
483 gotoXY(TAB + 24, 7);
484 ClearEoln();
485 FLUSH_SCANW("%s", s);
487 if (s[0] == '#')
489 for (sq = 0; sq < NO_SQUARES; sq++)
491 board[sq] = no_piece;
492 color[sq] = neutral;
493 DrawPiece(sq);
496 ClearCaptured();
497 UpdateCatched();
500 if (s[0] == 'c')
501 a = otherside[a];
503 if (s[1] == '*')
505 for (i = NO_PIECES; i > no_piece; i--)
507 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
508 break;
511 Captured[a][unpromoted[i]]++;
512 UpdateCatched();
513 c = -1;
515 else
517 c = COL_NAME(s[1]);
518 r = ROW_NAME(s[2]);
521 if ((c >= 0) && (c < NO_COLS) && (r >= 0) && (r < NO_ROWS))
523 sq = locn(r, c);
525 for (i = NO_PIECES; i > no_piece; i--)
527 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
528 break;
531 if (s[3] == '+')
532 i = promoted[i];
533 else
534 i = unpromoted[i];
536 board[sq] = i;
537 color[sq] = ((board[sq] == no_piece) ? neutral : a);
538 DrawPiece(sq);
541 while (s[0] != '.');
543 for (sq = 0; sq < NO_SQUARES; sq++)
544 Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
546 GameCnt = 0;
547 Game50 = 1;
548 ZeroRPT();
549 Sdepth = 0;
550 InitializeStats();
551 Curses_ClearScreen();
552 Curses_UpdateDisplay(0, 0, 1, 0);
556 static void
557 UpdateCatched()
559 short side;
561 for (side = black; side <= white; side++)
563 short x, y, piece, cside, k;
565 cside = flag.reverse ? (side ^ 1) : side;
566 x = x0[cside];
567 y = y0[cside];
568 k = 0;
570 for (piece = pawn; piece <= king; piece++)
572 short n;
574 if ((n = Captured[side][piece]))
576 gotoXY(x, y);
577 printw("%i%c", n, pxx[piece]);
579 if (cside == black)
580 y--;
581 else
582 y++;
584 else
586 k++;
590 while (k)
592 k--;
593 gotoXY(x, y);
594 printw(" ");
596 if (cside == black)
597 y--;
598 else
599 y++;
603 refresh();
607 void
608 Curses_SearchStartStuff(short side)
610 short i;
612 signal(SIGINT, Curses_TerminateSearch);
613 signal(SIGQUIT, Curses_TerminateSearch);
615 for (i = 4; i < 14; i++) /* CHECKME */
617 gotoXY(TAB, i);
618 ClearEoln();
623 void
624 Curses_OutputMove(void)
627 Curses_UpdateDisplay(root->f, root->t, 0, (short) root->flags);
628 gotoXY(TAB, 16);
630 if (flag.illegal)
632 printw("Illegal position.");
633 return;
636 printw("My move is: %5s", mvstr[0]);
638 if (flag.beep)
639 putchar(7);
641 ClearEoln();
643 gotoXY(TAB, 18);
645 if (root->flags & draw)
646 printw("Drawn game!");
647 else if (root->score == -(SCORE_LIMIT + 999))
648 printw("Opponent mates!");
649 else if (root->score == SCORE_LIMIT + 998)
650 printw("Computer mates!");
651 #ifdef VERYBUGGY
652 else if (root->score < -SCORE_LIMIT)
653 printw("Opp: mate in %d!", SCORE_LIMIT + 999 + root->score - 1);
654 else if (root->score > SCORE_LIMIT)
655 printw("Comp: mate in %d!", SCORE_LIMIT + 998 - root->score - 1);
656 #endif /* VERYBUGGY */
658 ClearEoln();
660 if (flag.post)
662 short h, l, t;
664 h = TREE;
665 l = 0;
666 t = TREE >> 1;
668 while (l != t)
670 if (Tree[t].f || Tree[t].t)
671 l = t;
672 else
673 h = t;
675 t = (l + h) >> 1;
678 ShowNodeCnt(NodeCnt);
679 gotoXY(TAB, 23);
680 printw("Max Tree = %5d", t);
681 ClearEoln();
684 Curses_ShowSidetoMove();
688 void
689 Curses_UpdateClocks(void)
691 short m, s;
692 long dt;
694 if (TCflag)
696 m = (short) ((dt = (TimeControl.clock[player] - et)) / 6000);
697 s = (short) ((dt - 6000 * (long) m) / 100);
699 else
701 m = (short) ((dt = et) / 6000);
702 s = (short) (et - 6000 * (long) m) / 100;
705 if (m < 0)
706 m = 0;
708 if (s < 0)
709 s = 0;
711 if (player == black)
712 gotoXY(20, (flag.reverse) ? 2 : 23);
713 else
714 gotoXY(20, (flag.reverse) ? 23 : 2);
716 /* printw("%d:%02d %ld ", m, s, dt); */
717 printw("%d:%02d ", m, s);
719 if (flag.post)
720 ShowNodeCnt(NodeCnt);
722 refresh();
726 static void
727 DrawPiece(short sq)
729 char y;
730 char piece, l, r, p;
732 if (color[sq] == neutral)
734 l = r = ' ';
736 else if (flag.reverse ^ (color[sq] == black))
738 l = '/';
739 r = '\\';
741 else
743 l = '\\', r = '/';
746 piece = board[sq];
748 if (is_promoted[(int)piece])
750 p = '+';
751 y = pxx[unpromoted[(int)piece]];
753 else
755 p = ' ';
756 y = pxx[(int)piece];
759 gotoXY(8 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
760 printw("%c%c%c%c", l, p, y, r);
765 * Curses_ShowPostnValue(): must have called ExaminePosition() first
767 void
768 Curses_ShowPostnValue(short sq)
770 short score;
772 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq))); /* CHECKME */
773 score = ScorePosition(color[sq]);
775 if (color[sq] != neutral)
776 #if defined SAVE_SVALUE
778 printw("??? ");
780 #else
782 printw("%3d ", svalue[sq]);
784 #endif
785 else
787 printw(" ");
792 void
793 Curses_ShowPostnValues(void)
795 short sq, score;
797 ExaminePosition(opponent);
799 for (sq = 0; sq < NO_SQUARES; sq++)
800 Curses_ShowPostnValue(sq);
802 score = ScorePosition(opponent);
803 gotoXY(TAB, 5);
804 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
805 mtl[computer], pscore[computer], GameType[computer],
806 mtl[opponent], pscore[opponent], GameType[opponent]);
808 ClearEoln();
812 void
813 Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
815 short i, sq, z;
816 int j;
818 if (redraw)
820 ShowHeader();
821 ShowPlayers();
823 i = 2;
824 gotoXY(3, ++i);
826 printw(" +");
827 for (j=0; j<NO_COLS; j++)
828 printw("----+");
830 while (i <= 1 + 2*NO_ROWS)
832 gotoXY(1, ++i);
834 if (flag.reverse)
835 z = (i / 2) - 1;
836 else
837 z = NO_ROWS + 2 - ((i + 1) / 2);
839 printw(" %c |", ROW_NAME(z+1));
840 for (j=0; j<NO_COLS; j++)
841 printw(" |");
843 gotoXY(3, ++i);
845 if (i < 2 + 2*NO_ROWS)
847 printw(" +");
848 for (j=0; j<NO_COLS; j++)
849 printw("----+");
853 printw(" +");
854 for (j=0; j<NO_COLS; j++)
855 printw("----+");
857 gotoXY(3, 4 + 2*NO_ROWS);
858 printw(" ");
860 #ifndef MINISHOGI
861 if (flag.reverse)
862 printw(" 1 2 3 4 5 6 7 8 9");
863 else
864 printw(" 9 8 7 6 5 4 3 2 1");
865 #else
866 if (flag.reverse)
867 printw(" 1 2 3 4 5");
868 else
869 printw(" 1 2 3 4 5");
870 #endif
872 for (sq = 0; sq < NO_SQUARES; sq++)
873 DrawPiece(sq);
875 else /* not redraw */
877 if (f < NO_SQUARES)
878 DrawPiece(f);
880 DrawPiece(t & 0x7f);
883 if ((isspec & capture) || (isspec & dropmask) || redraw)
885 short side;
887 for (side = black; side <= white; side++)
889 short x, y, piece, cside, k;
890 cside = flag.reverse ? (side ^ 1) : side;
891 x = x0[cside];
892 y = y0[cside];
893 k = 0;
895 for (piece = pawn; piece <= king; piece++)
897 short n;
899 if ((n = Captured[side][piece]))
901 gotoXY(x, y);
902 printw("%i%c", n, pxx[piece]);
904 if (cside == black) y--; else y++;
906 else
908 k++;
912 while (k)
914 k--;
915 gotoXY(x, y);
916 printw(" ");
918 if (cside == black)
919 y--;
920 else
921 y++;
926 refresh();
930 void
931 Curses_ChangeAlphaWindow(void)
933 Curses_ShowMessage("WAwindow = ");
934 FLUSH_SCANW("%hd", &WAwindow);
935 Curses_ShowMessage("BAwindow = ");
936 FLUSH_SCANW("%hd", &BAwindow);
940 void
941 Curses_ChangeBetaWindow(void)
943 Curses_ShowMessage("WBwindow = ");
944 FLUSH_SCANW("%hd", &WBwindow);
945 Curses_ShowMessage("BBwindow = ");
946 FLUSH_SCANW("%hd", &BBwindow);
950 void
951 Curses_GiveHint(void)
953 char s[40];
955 if (hint)
957 algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
958 strcpy(s, "try ");
959 strcat(s, mvstr[0]);
960 Curses_ShowMessage(s);
962 else
964 Curses_ShowMessage("I have no idea.\n");
969 void
970 Curses_ChangeSearchDepth(void)
972 Curses_ShowMessage("depth = ");
973 FLUSH_SCANW("%hd", &MaxSearchDepth);
974 TCflag = !(MaxSearchDepth > 0);
978 void
979 Curses_ChangeHashDepth(void)
981 Curses_ShowMessage("hashdepth = ");
982 FLUSH_SCANW("%hd", &HashDepth);
983 Curses_ShowMessage("MoveLimit = ");
984 FLUSH_SCANW("%hd", &HashMoveLimit);
988 void
989 Curses_SetContempt(void)
991 Curses_ShowMessage("contempt = ");
992 FLUSH_SCANW("%hd", &contempt);
996 void
997 Curses_ChangeXwindow(void)
999 Curses_ShowMessage("xwndw= ");
1000 FLUSH_SCANW("%hd", &xwndw);
1004 void
1005 Curses_SelectLevel(char *sx)
1007 int item;
1009 Curses_ClearScreen();
1010 gotoXY(32, 2);
1011 printw("GNU Shogi %s", PACKAGE_VERSION);
1012 gotoXY(20, 4);
1013 printw(" 1. 40 moves in 5 minutes");
1014 gotoXY(20, 5);
1015 printw(" 2. 40 moves in 15 minutes");
1016 gotoXY(20, 6);
1017 printw(" 3. 40 moves in 30 minutes");
1018 gotoXY(20, 7);
1019 printw(" 4. all moves in 15 minutes");
1020 gotoXY(20, 8);
1021 printw(" 5. all moves in 30 minutes");
1022 gotoXY(20, 9);
1023 printw(" 6. all moves in 15 minutes, 30 seconds fischer clock");
1024 gotoXY(20, 10);
1025 printw(" 7. all moves in 30 minutes, 30 seconds fischer clock");
1026 gotoXY(20, 11);
1027 printw(" 8. 1 move in 1 minute");
1028 gotoXY(20, 12);
1029 printw(" 9. 1 move in 15 minutes");
1030 gotoXY(20, 13);
1031 printw("10. 1 move in 30 minutes");
1033 OperatorTime = 0;
1034 TCmoves = 40;
1035 TCminutes = 5;
1036 TCseconds = 0;
1038 gotoXY(20, 17);
1039 printw("Enter Level: ");
1040 refresh();
1041 FLUSH_SCANW("%d", &item);
1043 switch(item)
1045 case 1:
1046 TCmoves = 40;
1047 TCminutes = 5;
1048 break;
1050 case 2:
1051 TCmoves = 40;
1052 TCminutes = 15;
1053 break;
1055 case 3:
1056 TCmoves = 40;
1057 TCminutes = 30;
1058 break;
1060 case 4:
1061 TCmoves = 80;
1062 TCminutes = 15;
1063 flag.gamein = true;
1064 break;
1066 case 5:
1067 TCmoves = 80;
1068 TCminutes = 30;
1069 flag.gamein = true;
1070 break;
1072 case 6:
1073 TCmoves = 80;
1074 TCminutes = 15;
1075 TCadd = 3000;
1076 flag.gamein = true;
1077 break;
1079 case 7:
1080 TCmoves = 80;
1081 TCminutes = 30;
1082 TCadd = 3000;
1083 break;
1085 case 8:
1086 TCmoves = 1;
1087 TCminutes = 1;
1088 flag.onemove = true;
1089 break;
1091 case 9:
1092 TCmoves = 1;
1093 TCminutes = 15;
1094 flag.onemove = true;
1095 break;
1097 case 10:
1098 TCmoves = 1;
1099 TCminutes = 30;
1100 flag.onemove = true;
1101 break;
1104 TCflag = (TCmoves > 0);
1106 TimeControl.clock[black] = TimeControl.clock[white] = 0;
1108 SetTimeControl();
1109 Curses_ClearScreen();
1110 Curses_UpdateDisplay(0, 0, 1, 0);
1114 void
1115 Curses_DoDebug(void)
1117 short c, p, sq, tp, tc, tsq, score;
1118 char s[40];
1120 ExaminePosition(opponent);
1121 Curses_ShowMessage("Enter piece: ");
1122 FLUSH_SCANW("%s", s);
1123 c = neutral;
1125 if ((s[0] == 'b') || (s[0] == 'B'))
1126 c = black;
1128 if ((s[0] == 'w') || (s[0] == 'W'))
1129 c = white;
1131 for (p = king; p > no_piece; p--)
1133 if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
1134 break;
1137 for (sq = 0; sq < NO_SQUARES; sq++)
1139 tp = board[sq];
1140 tc = color[sq];
1141 board[sq] = p;
1142 color[sq] = c;
1143 tsq = PieceList[c][1];
1144 PieceList[c][1] = sq;
1145 Curses_ShowPostnValue(sq);
1146 PieceList[c][1] = tsq;
1147 board[sq] = tp;
1148 color[sq] = tc;
1151 score = ScorePosition(opponent);
1152 gotoXY(TAB, 5);
1153 printw("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
1154 mtl[computer], pscore[computer], GameType[computer],
1155 mtl[opponent], pscore[opponent], GameType[opponent]);
1157 ClearEoln();
1161 void
1162 Curses_DoTable(short table[NO_SQUARES])
1164 short sq;
1165 ExaminePosition(opponent);
1167 for (sq = 0; sq < NO_SQUARES; sq++)
1169 gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));
1170 printw("%3d ", table[sq]);
1175 void
1176 Curses_PollForInput(void)
1178 int i;
1179 int nchar;
1181 if ((i = ioctl((int) 0, FIONREAD, &nchar)))
1183 perror("FIONREAD");
1184 fprintf(stderr,
1185 "You probably have a non-ANSI <ioctl.h>; "
1186 "see README. %d %d %x\n",
1187 i, errno, FIONREAD);
1188 exit(1);
1191 if (nchar)
1193 if (!flag.timeout)
1194 flag.back = true;
1196 flag.bothsides = false;
1201 void
1202 Curses_SetupBoard(void)
1204 Curses_ShowMessage("'setup' command is not supported in Cursesmode");