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