Convert more stuff from #ifdef to dspwrappers.
[gnushogi.git] / gnushogi / cursesdsp.c
1 /*
2  * FILE: cursesdsp.c
3  *
4  *     Curses interface for GNU Shogi
5  *
6  * ----------------------------------------------------------------------
7  * Copyright (c) 1993, 1994, 1995 Matthias Mutz
8  * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
9  *
10  * GNU SHOGI is based on GNU CHESS
11  *
12  * Copyright (c) 1988, 1989, 1990 John Stanback
13  * Copyright (c) 1992 Free Software Foundation
14  *
15  * This file is part of GNU SHOGI.
16  *
17  * GNU Shogi is free software; you can redistribute it and/or modify it
18  * under the terms of the GNU General Public License as published by the
19  * Free Software Foundation; either version 3 of the License,
20  * or (at your option) any later version.
21  *
22  * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
23  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25  * for more details.
26  *
27  * You should have received a copy of the GNU General Public License along
28  * with GNU Shogi; see the file COPYING. If not, see
29  * <http://www.gnu.org/licenses/>.
30  * ----------------------------------------------------------------------
31  */
32
33
34 #include <ctype.h>
35 #include <signal.h>
36
37 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/file.h>
40 #include <curses.h>
41
42 #include "gnushogi.h"
43 #include "cursesdsp.h"
44
45 #define FLUSH_SCANW fflush(stdout), scanw
46
47 int mycnt1, mycnt2;
48
49 #define TAB (58)
50
51 #define VIR_C(s)  ((flag.reverse) ? (NO_COLS - 1 - column(s)) : column(s))
52 #define VIR_R(s)  ((flag.reverse) ? (NO_ROWS - 1 - row(s)) : row(s))
53
54 unsigned short MV[MAXDEPTH];
55 int MSCORE;
56 char *DRAW;
57
58 /* Forward declarations. */
59 /* FIXME: change this name, puh-leeze! */
60
61 static void UpdateCatched(void);
62
63
64 /****************************************
65  * Trivial output functions.
66  ****************************************/
67
68 void
69 ClearEoln(void)
70 {
71     clrtoeol();
72     refresh();
73 }
74
75
76 void
77 Curses_ClearScreen(void)
78 {
79     clear();
80     refresh();
81 }
82
83
84 void
85 ClearMessage(void)
86 {
87     gotoXY(TAB, 6);
88     ClearEoln();
89 }
90
91
92
93 void
94 gotoXY(short x, short y)
95 {
96     move(y - 1, x - 1);
97 }
98
99
100 void
101 Curses_ShowCurrentMove(short pnt, short f, short t)
102 {
103     algbr(f, t, false);
104     gotoXY(TAB, 7);
105     printw("(%2d) %5s ", pnt, mvstr[0]);
106 }
107
108
109 void
110 Curses_ShowDepth(char ch)
111 {
112     gotoXY(TAB, 4);
113     printw(CP[53], Sdepth, ch);   /* Depth = %d%c */
114     ClearEoln();
115 }
116
117
118 void
119 Curses_ShowGameType(void)
120 {
121     if (flag.post)
122     {
123         gotoXY(TAB, 20);
124         printw("%c vs. %c", GameType[black], GameType[white]);
125     }
126 }
127
128
129 void
130 ShowHeader(void)
131 {
132     gotoXY(TAB, 2);
133     printw(CP[69], version, patchlevel);
134 }
135
136
137 void
138 Curses_ShowLine(unsigned short *bstline)
139 {
140 }
141
142
143 void
144 Curses_ShowMessage(char *s)
145 {
146     gotoXY(TAB, 6);
147     printw("%s", s);
148     ClearEoln();
149 }
150
151
152 void
153 Curses_Printf(const char *format, ...)
154 {
155     static char buffer[60];
156     va_list ap;
157     va_start(ap, format);
158     vsnprintf(buffer, sizeof(buffer), format, ap);
159     printw("%s", buffer);
160     va_end(ap);
161 }
162
163
164 void
165 Curses_RequestInputString(char* buffer)
166 {
167     FLUSH_SCANW("%s", buffer);
168 }
169
170
171 void
172 ShowNodeCnt(long NodeCnt)
173 {
174     gotoXY(TAB, 22);
175     /* printw(CP[90], NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0); */
176     printw("n = %ld n/s = %ld", 
177            NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0);
178     ClearEoln();
179 }
180
181
182 void
183 Curses_ShowPatternCount(short side, short n)
184 {
185     if (flag.post)
186     {
187         gotoXY(TAB + 10 + 3 * side, 20);          /* CHECKME */
188
189         if (n >= 0)
190             printw("%3d", n);
191         else
192             printw("   ");
193     }
194 }
195
196
197 void
198 ShowPlayers(void)
199 {
200     gotoXY(5, ((flag.reverse) ? (5 + 2*NO_ROWS) : 2));
201     printw("%s", (computer == white) ? CP[218] : CP[74]);
202     gotoXY(5, ((flag.reverse) ? 2 : (5 + 2*NO_ROWS)));
203     printw("%s", (computer == black) ? CP[218] : CP[74]);
204 }
205
206
207 void
208 ShowPrompt(void)
209 {
210     gotoXY(TAB, 17);
211     printw(CP[121]);     /* Your move is? */
212     ClearEoln();
213 }
214
215
216 void
217 Curses_ShowResponseTime(void)
218 {
219     if (flag.post)
220     {
221         short TCC = TCcount;
222         gotoXY(TAB, 21);
223         /* printw("RT = %ld TCC = %d TCL = %ld EX = %ld ET = %ld TO = %d",
224            ResponseTime, TCC, TCleft, ExtraTime, et, flag.timeout); */
225         printw("%ld, %d, %ld, %ld, %ld, %d",
226                ResponseTime, TCC, TCleft, ExtraTime, et, flag.timeout);
227         ClearEoln();
228     }
229 }
230
231
232 void
233 Curses_ShowResults(short score, unsigned short *bstline, char ch)
234 {
235     unsigned char d, ply;
236
237     if (flag.post)
238     {
239         Curses_ShowDepth(ch);
240         ShowScore(score);
241         d = 7;
242
243         for (ply = 1; bstline[ply] > 0; ply++)
244         {
245             if (ply % 2 == 1)
246             {
247                 gotoXY(TAB, ++d);
248                 ClearEoln();
249             }
250
251             algbr((short) bstline[ply] >> 8, 
252                   (short) bstline[ply] & 0xFF, false);
253             printw("%5s ", mvstr[0]);
254         }
255
256         ClearEoln();
257
258         while (d < 13)
259         {
260             gotoXY(TAB, ++d);
261             ClearEoln();
262         }
263     }
264 }
265
266
267 void
268 ShowScore(short score)
269 {
270     gotoXY(TAB, 5);
271     printw(CP[104], score);
272     ClearEoln();
273 }
274
275
276 void
277 Curses_ShowSidetoMove(void)
278 {
279     gotoXY(TAB, 14);
280     printw("%2d:   %s", 1 + GameCnt / 2, ColorStr[player]);
281     ClearEoln();
282 }
283
284
285 void
286 Curses_ShowStage(void)
287 {
288     gotoXY(TAB, 19);
289     printw("Stage= %2d%c B= %2d W= %2d",
290            stage, flag.tsume?'T':' ', balance[black], balance[white]);
291     ClearEoln();
292 }
293
294
295 /****************************************
296  * End of trivial output routines.
297  ****************************************/
298
299
300 void
301 Curses_Initialize(void)
302 {
303     signal(SIGINT, Curses_Die);
304     signal(SIGQUIT, Curses_Die);
305     initscr();
306     crmode();
307 }
308
309
310 void
311 Curses_ExitShogi(void)
312
313     if (!nolist)
314         ListGame();
315
316     gotoXY(1, 24);
317
318     refresh();
319     nocrmode();
320     endwin();
321
322     exit(0);
323 }
324
325
326
327 void
328 Curses_Die(int sig)
329 {
330     char s[80];
331
332     signal(SIGINT, SIG_IGN);
333     signal(SIGQUIT, SIG_IGN);
334
335     Curses_ShowMessage(CP[31]);     /* Abort? */
336     FLUSH_SCANW("%s", s);
337
338     if (strcmp(s, CP[210]) == 0) /* yes */
339         Curses_ExitShogi();
340
341     signal(SIGINT, Curses_Die);
342     signal(SIGQUIT, Curses_Die);
343 }
344
345
346
347 void
348 Curses_TerminateSearch(int sig)
349 {
350     signal(SIGINT, SIG_IGN);
351     signal(SIGQUIT, SIG_IGN);
352
353     if (!flag.timeout)
354         flag.musttimeout = true;
355
356     Curses_ShowMessage("Terminate Search");
357     flag.bothsides = false;
358     signal(SIGINT, Curses_Die);
359     signal(SIGQUIT, Curses_Die);
360 }
361
362
363
364 void
365 Curses_help(void)
366 {
367     Curses_ClearScreen();
368     /* printw("GNU Shogi ??p? command summary\n"); */
369     printw(CP[40], version, patchlevel);
370     printw("-------------------------------"
371            "---------------------------------\n");
372     /* printw("7g7f      move from 7g to 7f      quit      
373      * Exit Shogi\n"); */
374     printw(CP[158]);
375     /* printw("S6h       move silver to 6h       beep      
376      * turn %s\n", (flag.beep) ? "off" : "on"); */
377     printw(CP[86], (flag.beep) ? CP[92] : CP[93]);
378     /* printw("2d2c+     move to 2c and promote\n"); */
379     printw(CP[128], (flag.material) ? CP[92] : CP[93]);
380     /* printw("P*5e      drop a pawn to 5e       easy      
381      * turn %s\n", (flag.easy) ? "off" : "on"); */
382     printw(CP[173], (flag.easy) ? CP[92] : CP[93]);
383     /* printw("                                  hash      
384      * turn %s\n", (flag.hash) ? "off" : "on"); */
385     printw(CP[174], (flag.hash) ? CP[92] : CP[93]);
386     /* printw("bd        redraw board            reverse   
387      * board display\n"); */
388     printw(CP[130]);
389     /* printw("list      game to shogi.lst       book      
390      * turn %s used %d of %d\n", (Book) ? "off" : "on", book
391       count, booksize); */
392     printw(CP[170], (Book) ? CP[92] : CP[93], bookcount, BOOKSIZE);
393     /* printw("undo      undo last ply           remove    
394      * take back a move\n"); */
395     printw(CP[200]);
396     /* printw("edit      edit board              force     
397      * enter game moves\n"); */
398     printw(CP[153]);
399     /* printw("switch    sides with computer     both      
400      * computer match\n"); */
401     printw(CP[194]);
402     /* printw("black     computer plays black    white     
403      * computer plays white\n"); */
404     printw(CP[202]);
405     /* printw("depth     set search depth        clock     
406      * set time control\n"); */
407     printw(CP[149]);
408     /* printw("hint      suggest a move         post      
409      * turn %s principle variation\n", (flag.post) ? "off" :
410      * "on"); */
411     printw(CP[177], (flag.post) ? CP[92] : CP[93]);
412     /* printw("save      game to file            get       
413      * game from file\n"); */
414     printw(CP[188]);
415     /* printw("random    randomize play          new       
416      * start new game\n"); */
417     printw(CP[181]);
418     gotoXY(10, 20);
419     printw(CP[47], ColorStr[computer]);
420     gotoXY(10, 21);
421     printw(CP[97], ColorStr[opponent]);
422     gotoXY(10, 22);
423     printw(CP[79], MaxResponseTime/100);
424     gotoXY(10, 23);
425     printw(CP[59], (flag.easy) ? CP[93] : CP[92]);
426     gotoXY(25, 23);
427     printw(CP[231], (flag.tsume) ? CP[93] : CP[92]);
428     gotoXY(40, 20);
429     printw(CP[52], MaxSearchDepth);
430     gotoXY(40, 21);
431     printw(CP[100], (dither) ? CP[93] : CP[92]);
432     gotoXY(40, 22);
433     printw(CP[112], (flag.hash) ? CP[93] : CP[92]);
434     gotoXY(40, 23);
435     printw(CP[73]);
436     gotoXY(10, 24);
437     printw(CP[110], (TCflag) ? CP[93] : CP[92],
438            TimeControl.moves[black], 
439            TimeControl.clock[black] / 100, 
440            OperatorTime, MaxSearchDepth);
441
442     refresh();
443
444 #ifdef BOGUS
445     fflush(stdin); /* what is this supposed to do?? */
446 #endif /* BOGUS */
447
448     getchar();
449     Curses_ClearScreen();
450     Curses_UpdateDisplay(0, 0, 1, 0);
451 }
452
453
454 static const short x0[2] = { 54, 2 };
455 static const short y0[2] = { 20, 4 };
456
457
458 /*
459  * Set up a board position. Pieces are entered by typing the piece followed
460  * by the location. For example, N3f will place a knight on square 3f.
461  * P* will put a pawn to the captured pieces.
462  */
463
464 void
465 Curses_EditBoard(void)
466 {
467     short a, c, sq, i;
468     short r = 0;
469     char s[80];
470
471     flag.regularstart = true;
472     Book = BOOKFAIL;
473     Curses_ClearScreen();
474     Curses_UpdateDisplay(0, 0, 1, 0);
475     gotoXY(TAB, 3);
476     printw(CP[29]);
477     gotoXY(TAB, 4);
478     printw(CP[28]);
479     gotoXY(TAB, 5);
480     printw(CP[136]);
481     gotoXY(TAB, 7);
482     printw(CP[64]);
483     a = black;
484
485     do
486     {
487         gotoXY(TAB, 6);
488         printw(CP[60], ColorStr[a]); /* Editing %s */
489         gotoXY(TAB + 24, 7);
490         ClearEoln();
491         FLUSH_SCANW("%s", s);
492
493         if (s[0] == CP[28][0])    /* # */
494         {
495             for (sq = 0; sq < NO_SQUARES; sq++)
496             {
497                 board[sq] = no_piece;
498                 color[sq] = neutral;
499                 DrawPiece(sq);
500             }
501
502             ClearCaptured();
503             UpdateCatched();
504         }
505
506         if (s[0] == CP[136][0])   /* c */
507             a = otherside[a];
508
509         if (s[1] == '*')
510         {
511             for (i = NO_PIECES; i > no_piece; i--)
512             {
513                 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
514                     break;
515             }
516
517             Captured[a][unpromoted[i]]++;
518             UpdateCatched();
519             c = -1;
520         }
521         else
522         {
523             c = COL_NAME(s[1]);
524             r = ROW_NAME(s[2]);
525         }
526
527         if ((c >= 0) && (c < NO_COLS) && (r >= 0) && (r < NO_ROWS))
528         {
529             sq = locn(r, c);
530
531             for (i = NO_PIECES; i > no_piece; i--)
532             {
533                 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
534                     break;
535             }
536
537             if (s[3] == '+')
538                 i = promoted[i];
539             else
540                 i = unpromoted[i];
541
542             board[sq] = i;
543             color[sq] = ((board[sq] == no_piece) ? neutral : a);
544             DrawPiece(sq);
545         }
546     }
547     while (s[0] != CP[29][0]);  /* . */
548
549     for (sq = 0; sq < NO_SQUARES; sq++)
550         Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
551
552     GameCnt = 0;
553     Game50 = 1;
554     ZeroRPT();
555     Sdepth = 0;
556     InitializeStats();
557     Curses_ClearScreen();
558     Curses_UpdateDisplay(0, 0, 1, 0);
559 }
560
561
562
563 static void 
564 UpdateCatched()
565 {
566     short side;
567
568     for (side = black; side <= white; side++)
569     { 
570         short x, y, piece, cside, k;
571
572         cside = flag.reverse ? (side ^ 1) : side;
573         x = x0[cside];
574         y = y0[cside];
575         k = 0;
576
577         for (piece = pawn; piece <= king; piece++)
578         {
579             short n;
580
581             if ((n = Captured[side][piece]))
582             {
583                 gotoXY(x, y); 
584                 printw("%i%c", n, pxx[piece]);
585
586                 if (cside == black) 
587                     y--; 
588                 else 
589                     y++;
590             }
591             else
592             {
593                 k++;
594             }
595         }
596
597         while (k)
598         {
599             k--;
600             gotoXY(x, y);
601             printw("  ");
602
603             if (cside == black) 
604                 y--; 
605             else 
606                 y++;
607         }
608     }
609
610     refresh();
611 }
612
613
614
615 void
616 Curses_SearchStartStuff(short side)
617 {
618     short i;
619
620     signal(SIGINT, Curses_TerminateSearch);
621     signal(SIGQUIT, Curses_TerminateSearch);
622
623     for (i = 4; i < 14; i++)                      /* CHECKME */
624     {
625         gotoXY(TAB, i);
626         ClearEoln();
627     }
628 }
629
630
631
632 void
633 Curses_OutputMove(void)
634 {
635
636     Curses_UpdateDisplay(root->f, root->t, 0, (short) root->flags);
637     gotoXY(TAB, 16);
638
639     if (flag.illegal) 
640     {
641         printw(CP[225]);
642         return;
643     }
644
645     printw(CP[84], mvstr[0]);    /* My move is %s */
646
647     if (flag.beep)
648         putchar(7);
649
650     ClearEoln();
651
652     gotoXY(TAB, 18);
653
654     if (root->flags & draw)
655         printw(CP[58]);
656     else if (root->score == -(SCORE_LIMIT + 999))
657         printw(CP[95]);
658     else if (root->score == SCORE_LIMIT + 998)
659         printw(CP[44]);
660 #ifdef VERYBUGGY
661     else if (root->score < -SCORE_LIMIT)
662         printw(CP[96], SCORE_LIMIT + 999 + root->score - 1);
663     else if (root->score > SCORE_LIMIT)
664         printw(CP[45], SCORE_LIMIT + 998 - root->score - 1);
665 #endif /* VERYBUGGY */
666
667     ClearEoln();
668
669     if (flag.post)
670     {
671         short h, l, t;
672
673         h = TREE;
674         l = 0;
675         t = TREE >> 1;
676
677         while (l != t)
678         {
679             if (Tree[t].f || Tree[t].t)
680                 l = t;
681             else
682                 h = t;
683
684             t = (l + h) >> 1;
685         }
686
687         ShowNodeCnt(NodeCnt);
688         gotoXY(TAB, 23);
689         printw(CP[81], t); /* Max Tree= */
690         ClearEoln();
691     }
692
693     Curses_ShowSidetoMove();
694 }
695
696
697
698 void
699 UpdateClocks(void)
700 {
701     short m, s;
702     long dt;
703
704     if (TCflag)
705     {
706         m = (short) ((dt = (TimeControl.clock[player] - et)) / 6000);
707         s = (short) ((dt - 6000 * (long) m) / 100);
708     }
709     else
710     {
711         m = (short) ((dt = et) / 6000);
712         s = (short) (et - 6000 * (long) m) / 100;
713     }
714
715     if (m < 0)
716         m = 0;
717
718     if (s < 0)
719         s = 0;
720
721     if (player == black)
722         gotoXY(20, (flag.reverse) ? 2 : 23);
723     else
724         gotoXY(20, (flag.reverse) ? 23 : 2);
725
726     /* printw("%d:%02d %ld  ", m, s, dt); */
727     printw("%d:%02d  ", m, s); 
728
729     if (flag.post)
730         ShowNodeCnt(NodeCnt);
731
732     refresh();
733 }
734
735
736
737 void
738 DrawPiece(short sq)
739 {
740     char y;
741     char piece, l, r, p; 
742
743     if (color[sq] == neutral)
744     {
745         l = r = ' ';
746     }
747     else if (flag.reverse ^ (color[sq] == black))
748     {
749         l = '/';
750         r = '\\';
751     } 
752     else
753     {
754         l = '\\', r = '/';
755     }
756
757     piece = board[sq];
758
759     if (is_promoted[(int)piece])
760     {
761         p = '+';
762         y = pxx[unpromoted[(int)piece]];
763     } 
764     else
765     {
766         p = ' ';
767         y = pxx[(int)piece];
768     }
769
770     gotoXY(8 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
771     printw("%c%c%c%c", l, p, y, r);
772 }
773
774
775
776
777 /*
778  * Curses_ShowPostnValue(): must have called ExaminePosition() first
779  */
780
781 void
782 Curses_ShowPostnValue(short sq)
783 {
784     short score;
785
786     gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq))); /* CHECKME */
787     score = ScorePosition(color[sq]);
788
789     if (color[sq] != neutral)
790 #if defined SAVE_SVALUE
791     {
792         printw("??? ");
793     }
794 #else
795     {
796         printw("%3d ", svalue[sq]);
797     }
798 #endif
799     else
800     {
801         printw("   ");
802     }
803 }
804
805
806
807 void
808 Curses_ShowPostnValues(void)
809 {
810     short sq, score;
811
812     ExaminePosition(opponent);
813
814     for (sq = 0; sq < NO_SQUARES; sq++)
815         Curses_ShowPostnValue(sq);
816
817     score = ScorePosition(opponent);
818     gotoXY(TAB, 5);
819     printw(CP[103], score, 
820            mtl[computer], pscore[computer], GameType[computer],
821            mtl[opponent], pscore[opponent], GameType[opponent]);
822
823     ClearEoln();
824 }
825
826
827
828 void
829 Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
830 {
831     short i, sq, z;
832     int j;
833
834     if (redraw)
835     {
836         ShowHeader();
837         ShowPlayers();
838
839         i = 2;
840         gotoXY(3, ++i);
841
842         printw("    +");
843         for (j=0; j<NO_COLS; j++)
844             printw("----+");
845
846         while (i <= 1 + 2*NO_ROWS)
847         {
848             gotoXY(1, ++i);
849
850             if (flag.reverse)
851                 z = (i / 2) - 1;
852             else
853                 z = NO_ROWS + 2 - ((i + 1) / 2);
854
855             printw("    %c |", ROW_NAME(z+1));
856             for (j=0; j<NO_COLS; j++)
857                 printw("    |");
858
859             gotoXY(3, ++i);
860
861             if (i < 2 + 2*NO_ROWS)
862             {
863                 printw("    +");
864                 for (j=0; j<NO_COLS; j++)
865                     printw("----+");
866             }
867         }
868
869         printw("    +");
870         for (j=0; j<NO_COLS; j++)
871             printw("----+");
872
873         gotoXY(3, 4 + 2*NO_ROWS);
874         printw("    ");
875
876         if (flag.reverse)
877             printw(CP[16]);
878         else
879             printw(CP[15]);
880
881         for (sq = 0; sq < NO_SQUARES; sq++)
882             DrawPiece(sq);
883     }
884     else /* not redraw */
885     {
886         if (f < NO_SQUARES)
887             DrawPiece(f);
888
889         DrawPiece(t & 0x7f);
890     }
891
892     if ((isspec & capture) || (isspec & dropmask) || redraw)
893     {
894         short side;
895
896         for (side = black; side <= white; side++)
897         {
898             short x, y, piece, cside, k;
899             cside = flag.reverse ? (side ^ 1) : side;
900             x = x0[cside];
901             y = y0[cside];
902             k = 0;
903
904             for (piece = pawn; piece <= king; piece++)
905             {
906                 short n;
907
908                 if ((n = Captured[side][piece]))
909                 {
910                     gotoXY(x, y); 
911                     printw("%i%c", n, pxx[piece]);
912
913                     if (cside == black) y--; else y++;
914                 }
915                 else
916                 {
917                     k++;
918                 }
919             }
920
921             while (k)
922             {
923                 k--;
924                 gotoXY(x, y);
925                 printw("  ");
926
927                 if (cside == black) 
928                     y--;
929                 else 
930                     y++;
931             }
932         }
933     }
934
935     refresh();
936 }
937
938
939 extern char *InPtr;
940
941
942 void
943 Curses_ChangeAlphaWindow(void)
944 {
945     Curses_ShowMessage(CP[114]);
946     FLUSH_SCANW("%hd", &WAwindow);
947     Curses_ShowMessage(CP[34]);
948     FLUSH_SCANW("%hd", &BAwindow);
949 }
950
951
952
953 void
954 Curses_ChangeBetaWindow(void)
955 {
956     Curses_ShowMessage(CP[115]);
957     FLUSH_SCANW("%hd", &WBwindow);
958     Curses_ShowMessage(CP[35]);
959     FLUSH_SCANW("%hd", &BBwindow);
960 }
961
962
963
964 void
965 Curses_GiveHint(void)
966 {
967     char s[40];
968
969     if (hint)
970     {
971         algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
972         strcpy(s, CP[198]);  /* try */
973         strcat(s, mvstr[0]);
974         Curses_ShowMessage(s);
975     }
976     else
977     {
978         Curses_ShowMessage(CP[223]);
979     }
980 }
981
982
983
984 void
985 Curses_ChangeSearchDepth(void)
986 {
987     Curses_ShowMessage(CP[150]);
988     FLUSH_SCANW("%hd", &MaxSearchDepth);
989     TCflag = !(MaxSearchDepth > 0);
990 }
991
992
993 void
994 Curses_ChangeHashDepth(void)
995 {
996     Curses_ShowMessage(CP[163]);
997     FLUSH_SCANW("%hd", &HashDepth);
998     Curses_ShowMessage(CP[82]);
999     FLUSH_SCANW("%hd", &HashMoveLimit);
1000 }
1001
1002
1003 void
1004 Curses_SetContempt(void)
1005 {
1006     Curses_ShowMessage(CP[142]);
1007     FLUSH_SCANW("%hd", &contempt);
1008 }
1009
1010
1011
1012 void
1013 Curses_ChangeXwindow(void)
1014 {
1015     Curses_ShowMessage(CP[208]);
1016     FLUSH_SCANW("%hd", &xwndw);
1017 }
1018
1019
1020
1021 void
1022 Curses_SelectLevel(char *sx)
1023 {
1024     int item;
1025
1026     Curses_ClearScreen();
1027     gotoXY(32, 2);
1028     printw(CP[41], version, patchlevel);
1029     gotoXY(20, 4);
1030     printw(CP[18]);
1031     gotoXY(20, 5);
1032     printw(CP[19]);
1033     gotoXY(20, 6);
1034     printw(CP[20]);
1035     gotoXY(20, 7);
1036     printw(CP[21]);
1037     gotoXY(20, 8);
1038     printw(CP[22]);
1039     gotoXY(20, 9);
1040     printw(CP[23]);
1041     gotoXY(20, 10);
1042     printw(CP[24]);
1043     gotoXY(20, 11);
1044     printw(CP[25]);
1045     gotoXY(20, 12);
1046     printw(CP[26]);
1047     gotoXY(20, 13);
1048     printw(CP[27]);
1049
1050     OperatorTime = 0;
1051     TCmoves = 40;
1052     TCminutes = 5;
1053     TCseconds = 0;
1054
1055     gotoXY(20, 17);
1056     printw(CP[62]);
1057     refresh();
1058     FLUSH_SCANW("%d", &item);
1059
1060     switch(item)
1061     {
1062     case 1:
1063         TCmoves = 40;
1064         TCminutes = 5;
1065         break;
1066
1067     case 2:
1068         TCmoves = 40;
1069         TCminutes = 15;
1070         break;
1071
1072     case 3:
1073         TCmoves = 40;
1074         TCminutes = 30;
1075         break;
1076
1077     case 4:
1078         TCmoves = 80;
1079         TCminutes = 15;
1080         flag.gamein = true;
1081         break;
1082
1083     case 5:
1084         TCmoves = 80;
1085         TCminutes = 30;
1086         flag.gamein = true;
1087         break;
1088
1089     case 6:
1090         TCmoves = 80;
1091         TCminutes = 15;
1092         TCadd = 3000;
1093         flag.gamein = true;
1094         break;
1095
1096     case 7:
1097         TCmoves = 80;
1098         TCminutes = 30;
1099         TCadd = 3000;
1100         break;
1101
1102     case 8:
1103         TCmoves = 1;
1104         TCminutes = 1;
1105         flag.onemove = true;
1106         break;
1107
1108     case 9:
1109         TCmoves = 1;
1110         TCminutes = 15;
1111         flag.onemove = true;
1112         break;
1113
1114     case 10:
1115         TCmoves = 1;
1116         TCminutes = 30;
1117         flag.onemove = true;
1118         break;
1119     }
1120
1121     TCflag = (TCmoves > 0);
1122
1123     TimeControl.clock[black] = TimeControl.clock[white] = 0; 
1124
1125     SetTimeControl();
1126     Curses_ClearScreen();
1127     Curses_UpdateDisplay(0, 0, 1, 0);
1128 }
1129
1130
1131
1132 void
1133 Curses_DoDebug(void)
1134 {
1135     short c, p, sq, tp, tc, tsq, score;
1136     char s[40];
1137
1138     ExaminePosition(opponent);
1139     Curses_ShowMessage(CP[65]);
1140     FLUSH_SCANW("%s", s);
1141     c = neutral;
1142
1143     if ((s[0] == CP[9][0]) || (s[0] == CP[9][1])) /* b B */
1144         c = black;
1145
1146     if ((s[0] == CP[9][2]) || (s[0] == CP[9][3])) /* w W */
1147         c = white;
1148
1149     for (p = king; p > no_piece; p--)
1150     {
1151         if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
1152             break;
1153     }
1154
1155     for (sq = 0; sq < NO_SQUARES; sq++)
1156     {
1157         tp = board[sq];
1158         tc = color[sq];
1159         board[sq] = p;
1160         color[sq] = c;
1161         tsq = PieceList[c][1];
1162         PieceList[c][1] = sq;
1163         Curses_ShowPostnValue(sq);
1164         PieceList[c][1] = tsq;
1165         board[sq] = tp;
1166         color[sq] = tc;
1167     }
1168
1169     score = ScorePosition(opponent);
1170     gotoXY(TAB, 5);
1171     printw(CP[103], score, 
1172            mtl[computer], pscore[computer], GameType[computer],
1173            mtl[opponent], pscore[opponent], GameType[opponent]);
1174
1175     ClearEoln();
1176 }
1177
1178
1179
1180 void
1181 Curses_DoTable(short table[NO_SQUARES])
1182 {
1183     short  sq;
1184     ExaminePosition(opponent);
1185
1186     for (sq = 0; sq < NO_SQUARES; sq++)
1187     {
1188         gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));
1189         printw("%3d ", table[sq]);
1190     }
1191
1192
1193
1194