Improve calculation of thinking time in sudden-death games
[gnushogi.git] / gnushogi / rawdsp.c
1 /*
2  * FILE: rawdsp.c
3  *
4  * ----------------------------------------------------------------------
5  * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6  * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
7  * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
8  *
9  * GNU SHOGI is based on GNU CHESS
10  *
11  * Copyright (c) 1988, 1989, 1990 John Stanback
12  * Copyright (c) 1992 Free Software Foundation
13  *
14  * This file is part of GNU SHOGI.
15  *
16  * GNU Shogi is free software; you can redistribute it and/or modify it
17  * under the terms of the GNU General Public License as published by the
18  * Free Software Foundation; either version 3 of the License,
19  * or (at your option) any later version.
20  *
21  * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
22  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with GNU Shogi; see the file COPYING. If not, see
28  * <http://www.gnu.org/licenses/>.
29  * ----------------------------------------------------------------------
30  *
31  */
32
33 #include <ctype.h>
34 #include <signal.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/file.h>
40 #ifndef WIN32
41 #include <poll.h>
42 #include <unistd.h>
43 #endif
44
45 #include "gnushogi.h"
46
47 /****************************************
48  * forward declarations
49  ****************************************/
50
51 static void Raw_UpdateDisplay(short f, short t, short redraw, short isspec);
52
53 /****************************************
54  * Trivial output functions.
55  ****************************************/
56
57 static void
58 Raw_ClearScreen(void)
59 {
60     if (!XSHOGI)
61         printf("\n");
62 }
63
64
65 static void
66 Raw_ShowPrompt(void)
67 {
68     if (!XSHOGI)
69         fputs("\nYour move is? ", stdout);
70 }
71
72
73 static void
74 Raw_ShowCurrentMove(short pnt, short f, short t)
75 {
76 }
77
78
79 static void
80 Raw_ShowDepth(char ch)
81 {
82     if (!XSHOGI)
83         printf("Depth= %d%c \n", Sdepth, ch);
84 }
85
86
87 static void
88 Raw_ShowGameType(void)
89 {
90     if (flag.post)
91         printf("%c vs. %c\n", GameType[black], GameType[white]);
92 }
93
94
95 static void
96 Raw_ShowLine(unsigned short *bstline)
97 {
98     int i;
99
100     for (i = 1; bstline[i] > 0; i++)
101     {
102         if ((i > 1) && (i % 8 == 1))
103             printf("\n                          ");
104
105         algbr((short)(bstline[i] >> 8), (short)(bstline[i] & 0xFF), false);
106         printf("%5s ", mvstr[0]);
107     }
108
109     printf("\n");
110 }
111
112
113 static void
114 Raw_ShowMessage(char *format, ...)
115 {
116     if (XSHOGI)
117         return;
118     va_list ap;
119     va_start(ap, format);
120     vprintf(format, ap);
121     printf("\n");
122     va_end(ap);
123 }
124
125
126 static void
127 Raw_AlwaysShowMessage(const char *format, ...)
128 {
129     va_list ap;
130     va_start(ap, format);
131     vprintf(format, ap);
132     printf("\n");
133     va_end(ap);
134 }
135
136
137 static void
138 Raw_Printf(const char *format, ...)
139 {
140     va_list ap;
141     va_start(ap, format);
142     vprintf(format, ap);
143     va_end(ap);
144 }
145
146
147 static void
148 Raw_doRequestInputString(const char* fmt, char* buffer)
149 {
150     scanf(fmt, buffer);
151 }
152
153
154 static int
155 Raw_GetString(char* sx)
156 {
157     int eof = 0;
158     char *nl;
159     sx[0] = '\0';
160
161     while(!eof && !sx[0])
162         eof = (fgets(sx, 80, stdin) == NULL);
163
164     /* remove any trailing newline */
165     nl = strchr(sx, '\n');
166     if (nl)
167         nl[0] = '\0';
168
169     return eof;
170 }
171
172
173 static void
174 Raw_ShowNodeCnt(long NodeCnt)
175 {
176     printf("Nodes = %ld Nodes/sec = %ld\n",
177            NodeCnt, (((et) ? ((NodeCnt * 100) / et) : 0)));
178 }
179
180
181 static void
182 Raw_ShowPatternCount(short side, short n)
183 {
184     if (flag.post)
185         printf("%s%s matches %d pattern(s)\n", xboard ? "# " : "" , ColorStr[side], n);
186 }
187
188
189 static void
190 Raw_ShowResponseTime(void)
191 {
192 }
193
194
195 static void
196 Raw_ShowResults(short score, unsigned short *bstline, char ch)
197 {
198     if (flag.post && (xboard || !XSHOGI))
199     {
200         ElapsedTime(2);
201         printf("%2d%c %6d %4ld %8ld  ",
202                Sdepth, ch, score, et / 100, NodeCnt);
203         Raw_ShowLine(bstline);
204     }
205 }
206
207
208 static void
209 Raw_ShowSidetoMove(void)
210 {
211 }
212
213
214 static void
215 Raw_ShowStage(void)
216 {
217     printf("stage = %d\n", stage);
218     printf("balance[black] = %d balance[white] = %d\n",
219            balance[black], balance[white]);
220 }
221
222 /****************************************
223  * End of trivial output routines.
224  ****************************************/
225
226 static void
227 Raw_Initialize(void)
228 {
229     mycnt1 = mycnt2 = 0;
230
231     if (XSHOGI)
232     {
233 #ifdef WIN32
234         /* needed because of inconsistency between MSVC run-time system and gcc includes */
235         setbuf(stdout, NULL);
236 #else
237 #ifdef HAVE_SETVBUF
238         setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
239 #else
240 #  ifdef HAVE_SETLINEBUF
241         setlinebuf(stdout);
242 #  else
243 #    error "Need setvbuf() or setlinebuf() to compile gnushogi!"
244 #  endif
245 #endif
246 #endif
247         printf("GNU Shogi %s\n", PACKAGE_VERSION);
248     }
249
250     if (hard_time_limit)
251     {
252         if (!TCflag && (MaxResponseTime == 0))
253             MaxResponseTime = 15L * 100L;
254     }
255 }
256
257
258 static void
259 Raw_ExitShogi(void)
260 {
261     /* CHECKME: what purpose does this next statement serve? */
262     signal(SIGTERM, SIG_IGN);
263
264     if (!nolist)
265         ListGame();
266
267     exit(0);
268 }
269
270
271 static void
272 Raw_TerminateSearch(int sig)
273 {
274 #ifdef INTERRUPT_TEST
275     ElapsedTime(INIT_INTERRUPT_MODE);
276 #endif
277
278     if (!flag.timeout)
279         flag.back = true; /* previous: flag.timeout = true; */
280
281     flag.bothsides = false;
282 }
283
284
285 static void
286 Raw_help(void)
287 {
288     Raw_ClearScreen();
289     printf("GNU Shogi %s command summary\n", PACKAGE_VERSION);
290     printf("----------------------------------------------------------------\n");
291     printf("7g7f      move from 7g to 7f      quit      Exit Shogi\n");
292     printf("S6h       move silver to 6h       beep      turn %s\n",
293            (flag.beep) ? "OFF" : "ON");
294     printf("2d2c+     move to 2c and promote  material  turn %s\n",
295            (flag.material) ? "OFF" : "ON");
296     printf("P*5e      drop pawn to 5e         easy      turn %s\n",
297            (flag.easy) ? "OFF" : "ON");
298     printf("tsume     toggle tsume mode       hash      turn %s\n",
299            (flag.hash) ? "OFF" : "ON");
300     printf("bd        redraw board            reverse   board display\n");
301     printf("list      game to shogi.lst       book      turn %s used %d of %d\n",
302            (Book) ? "OFF" : "ON", bookcount, booksize);
303     printf("undo      undo last ply           remove    take back a move\n");
304     printf("edit      edit board              force     toggle manual move mode\n");
305     printf("switch    sides with computer     both      computer match\n");
306     printf("black     computer plays black    white     computer plays white\n");
307     printf("sd        set search depth        clock     set time control\n");
308     printf("post      principle variation     hint      suggest a move\n");
309     printf("save      game to file            get       game from file\n");
310     printf("xsave     pos. to xshogi file     xget      pos. from xshogi file\n");
311     printf("random    randomize play          new       start new game\n");
312     printf("setup                             first     \n");
313     printf("go        computer plays now      material  turn %s\n",
314            flag.material ? "OFF" : "ON");
315     printf("level     time control            gamein    \n");
316     printf("time      set engine clock        otime     set opponent clock\n");
317     printf("Awindow                           Bwindow     \n");
318     printf("rcptr     turn %3s                bsave     book save\n",
319            flag.rcptr ? "OFF" : "ON ");
320     printf("hashdepth                         hard      turn easy OFF\n");
321     printf("contempt                          xwndw                  \n");
322     printf("rv        turn %3s                coords    turn %s\n",
323            flag.rv ? "OFF" : "ON ", flag.coords ? "OFF" : "ON");
324     printf("stars     turn %3s                moves                  \n",
325            flag.stars ? "OFF" : "ON ");
326     printf("test                              p                      \n");
327     printf("debug                             depth     alias for 'sd'\n");
328     printf("----------------------------------------------------------------\n");
329     printf("Computer: %-12s Opponent:            %s\n",
330            ColorStr[computer], ColorStr[opponent]);
331     printf("Depth:    %-12d Response time:       %ld sec\n",
332            MaxSearchDepth, MaxResponseTime/100);
333     printf("Random:   %-12s Easy mode:           %s\n",
334            (dither) ? "ON" : "OFF", (flag.easy) ? "ON" : "OFF");
335     printf("Beep:     %-12s Transposition file:  %s\n",
336            (flag.beep) ? "ON" : "OFF", (flag.hash) ? "ON" : "OFF");
337     printf("Tsume:    %-12s Force:               %s\n",
338            (flag.tsume) ? "ON" : "OFF", (flag.force) ? "ON" : "OFF");
339     printf("Time Control %s %d moves %ld sec %d add %d depth\n",
340            (TCflag) ? "ON" : "OFF",
341            TimeControl.moves[black], TimeControl.clock[black] / 100,
342            TCadd/100, MaxSearchDepth);
343 }
344
345
346 /*
347  * Set up a board position. Pieces are entered by typing the piece followed
348  * by the location. For example, Nf3 will place a knight on square f3.
349  */
350 static void
351 Raw_EditBoard(void)
352 {
353     short a, r, c, sq, i, found;
354     char s[80];
355
356     flag.regularstart = true;
357     Book = BOOKFAIL;
358     Raw_ClearScreen();
359     Raw_UpdateDisplay(0, 0, 1, 0);
360     printf(".   Exit to main\n");
361     printf("#   Clear board\n");
362     printf("c   Change sides\n");
363     printf("enter piece & location:\n");
364
365     a = black;
366
367     while(1)
368     {
369         scanf("%s", s);
370         found = 0;
371
372         if (s[0] == '.')
373             break;
374
375         if (s[0] == '#')
376         {
377             for (sq = 0; sq < NO_SQUARES; sq++)
378             {
379                 board[sq] = no_piece;
380                 color[sq] = neutral;
381             }
382
383             ClearCaptured();
384             continue;
385         }
386
387         if (s[0] == 'c') {
388             a = otherside[a];
389             continue;
390         }
391
392         if (s[1] == '*')
393         {
394             for (i = pawn; i <= king; i++)
395             {
396                 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
397                 {
398                     Captured[a][i]++;
399                     found = 1;
400                     break;
401                 }
402             }
403             if (!found)
404                 printf("# Invalid piece type '%c'\n", s[0]);
405             continue;
406         }
407
408         c = COL_NUM(s[1]);
409         r = ROW_NUM(s[2]);
410
411         if ((c < 0) || (c >= NO_COLS) || (r < 0) || (r >= NO_ROWS)) {
412             printf("# Out-of-board position '%c%c'\n", s[1], s[2]);
413             continue;
414         }
415
416         sq = locn(r, c);
417
418         for (i = no_piece; i <= king; i++)
419         {
420             if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
421             {
422                 color[sq] = a;
423                 if (s[3] == '+')
424                     board[sq] = promoted[i];
425                 else
426                     board[sq] = i;
427
428                 found = 1;
429                 break;
430             }
431         }
432
433         if (!found)
434             printf("# Invalid piece type '%c'\n", s[0]);
435     }
436
437     for (sq = 0; sq < NO_SQUARES; sq++)
438         Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
439
440     GameCnt = 0;
441     Game50 = 1;
442     ZeroRPT();
443     Sdepth = 0;
444     InitializeStats();
445     Raw_ClearScreen();
446     Raw_UpdateDisplay(0, 0, 1, 0);
447 }
448
449
450 /*
451  * Set up a board position.
452  * Nine lines of nine characters are used to setup the board. 9a-1a is the
453  * first line. White pieces are  represented  by  uppercase characters.
454  */
455 static void
456 Raw_SetupBoard(void)
457 {
458     short r, c, sq, i;
459     char ch;
460     char s[80];
461
462     NewGame();
463
464     fgets(s, 80, stdin);            /* skip "setup" command */
465
466     for (r = NO_ROWS - 1; r >= 0; r--)
467     {
468         fgets(s, 80, stdin);
469
470         for (c = 0; c <= (NO_COLS - 1); c++)
471         {
472             ch = s[c];
473             sq = locn(r, c);
474             color[sq] = neutral;
475             board[sq] = no_piece;
476
477             for (i = no_piece; i <= king; i++)
478             {
479                 if (ch == pxx[i])
480                 {
481                     color[sq] = white;
482                     board[sq] = i;
483                     break;
484                 }
485                 else if (ch == qxx[i])
486                 {
487                     color[sq] = black;
488                     board[sq] = i;
489                     break;
490                 }
491             }
492         }
493     }
494
495     for (sq = 0; sq < NO_SQUARES; sq++)
496         Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
497
498     InitializeStats();
499     Raw_ClearScreen();
500     Raw_UpdateDisplay(0, 0, 1, 0);
501     fputs("Setup successful\n", stdout);
502 }
503
504
505 static void
506 Raw_SearchStartStuff(short side)
507 {
508     if (flag.post)
509     {
510         printf("\nMove# %d    Target = %ld    Clock: %ld\n",
511                GameCnt/2 + 1,
512                ResponseTime, TimeControl.clock[side]);
513     }
514 }
515
516
517 static void
518 Raw_OutputMove(void)
519 {
520     if (flag.illegal)
521     {
522         printf("Illegal position.\n");
523         return;
524     }
525
526     if (mvstr[0][0] == '\0')
527         goto nomove;
528
529     mycnt1++;
530     if (XSHOGI && xboard) /* xboard: print move in XBoard format, with 'move' prefix */
531         printf("move %s\n", mvstr[0]);
532     else if (XSHOGI)
533         /* add remaining time in milliseconds to xshogi */
534         printf("%d. ... %s %ld\n", mycnt1, mvstr[0],
535                (TimeControl.clock[player] - et) * 10);
536     else
537         printf("%d. ... %s\n", mycnt1, mvstr[0]);
538
539  nomove:
540     if ((root->flags & draw) || (root->score == -(SCORE_LIMIT + 999))
541         || (root->score == (SCORE_LIMIT + 998)))
542         goto summary;
543
544     if (flag.post)
545     {
546         short h, l, t;
547
548         h = TREE;
549         l = 0;
550         t = TREE >> 1;
551
552         while (l != t)
553         {
554             if (Tree[t].f || Tree[t].t)
555                 l = t;
556             else
557                 h = t;
558
559             t = (l + h) >> 1;
560         }
561
562         printf("Gen %ld Node %ld Tree %d Eval %ld Rate %ld EC %d/%d RS hi %ld lo %ld \n", GenCnt, NodeCnt, t, EvalNodes,
563                (et > 100) ? (NodeCnt / (et / 100)) : 0,
564                EADD, EGET, reminus, replus);
565
566         printf("Hin/Hout/Tcol/Coll/Fin/Fout = %ld/%ld/%ld/%ld/%ld/%ld\n",
567                HashAdd, HashCnt, THashCol, HashCol, FHashCnt, FHashAdd);
568     }
569
570     Raw_UpdateDisplay(root->f, root->t, 0, root->flags);
571
572     if (!XSHOGI)
573     {
574         printf("My move is: %5s\n", mvstr[0]);
575
576         if (flag.beep)
577             printf("%c", 7);
578     }
579
580  summary:
581     if (root->flags & draw)
582         fputs("Drawn game!\n", stdout);
583     else if (root->score == -(SCORE_LIMIT + 999))
584         printf("%s mates!\n", ColorStr[opponent]);
585     else if (root->score == (SCORE_LIMIT + 998))
586         printf("%s mates!\n", ColorStr[computer]);
587 #ifdef VERYBUGGY
588     else if (!XSHOGI && (root->score < -SCORE_LIMIT))
589         printf("%s%s has a forced mate in %d moves!\n", xboard ? "# " : "",
590                ColorStr[opponent], SCORE_LIMIT + 999 + root->score - 1);
591     else if (!XSHOGI && (root->score > SCORE_LIMIT))
592         printf("%s%s has a forced mate in %d moves!\n", xboard ? "# " : "",
593                ColorStr[computer], SCORE_LIMIT + 998 - root->score - 1);
594 #endif /* VERYBUGGY */
595 }
596
597
598 static void
599 Raw_UpdateClocks(void)
600 {
601 }
602
603
604 static void
605 Raw_UpdateDisplay(short f, short t, short redraw, short isspec)
606 {
607
608     short r, c, l, m;
609
610     if (redraw && !XSHOGI)
611     {
612         printf("\n");
613         r = (short)(TimeControl.clock[black] / 6000);
614         c = (short)((TimeControl.clock[black] % 6000) / 100);
615         l = (short)(TimeControl.clock[white] / 6000);
616         m = (short)((TimeControl.clock[white] % 6000) / 100);
617         printf("Black %d:%02d  White %d:%02d\n", r, c, l, m);
618         printf("\n");
619
620         for (r = (NO_ROWS - 1); r >= 0; r--)
621         {
622             for (c = 0; c <= (NO_COLS - 1); c++)
623             {
624                 char pc;
625                 l = ((flag.reverse)
626                      ? locn((NO_ROWS - 1) - r, (NO_COLS - 1) - c)
627                      : locn(r, c));
628                 pc = (is_promoted[board[l]] ? '+' : ' ');
629
630                 if (color[l] == neutral)
631                     printf(" -");
632                 else if (color[l] == black)
633                     printf("%c%c", pc, qxx[board[l]]);
634                 else
635                     printf("%c%c", pc, pxx[board[l]]);
636             }
637
638             printf("\n");
639         }
640
641         printf("\n");
642         {
643             short side;
644
645             for (side = black; side <= white; side++)
646             {
647                 short piece, c;
648                 printf((side == black)?"black ":"white ");
649
650                 for (piece = pawn; piece <= king; piece++)
651                 {
652                     if ((c = Captured[side][piece]))
653                         printf("%i%c ", c, pxx[piece]);
654                 }
655
656                 printf("\n");
657             }
658         }
659     }
660 }
661
662
663 static void
664 Raw_ChangeAlphaWindow(void)
665 {
666     printf("WAwindow: ");
667     scanf("%hd", &WAwindow);
668     printf("BAwindow: ");
669     scanf("%hd", &BAwindow);
670 }
671
672
673 static void
674 Raw_ChangeBetaWindow(void)
675 {
676     printf("WBwindow: ");
677     scanf("%hd", &WBwindow);
678     printf("BBwindow: ");
679     scanf("%hd", &BBwindow);
680 }
681
682
683 static void
684 Raw_GiveHint(void)
685 {
686     if (hint)
687     {
688         algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
689         printf("Hint: %s\n", mvstr[0]);
690     }
691     else
692         fputs("I have no idea.\n", stdout);
693 }
694
695
696 static void
697 Raw_SelectLevel(char *sx)
698 {
699     /* FIXME: NO_SQUARES is nonsense here */
700     char T[NO_SQUARES + 1], *p;
701
702     strncpy(T, sx, NO_SQUARES);
703     T[NO_SQUARES] = '\0';
704
705
706     if (!xboard) {
707         /* if line empty, ask for input */
708         if (!T[0])
709         {
710             fputs("Enter #moves #minutes: ", stdout);
711             fgets(T, NO_SQUARES + 1, stdin);
712         }
713     
714         /* skip blackspace */
715         for (p = T; *p == ' '; p++) ;
716     
717         /* could be moves or a fischer clock */
718         if (*p == 'f')
719         {
720             /* its a fischer clock game */
721             char *q;
722             p++;
723             TCminutes = (short)strtol(p, &q, 10);
724             TCadd = (short)strtol(q, NULL, 10) *100;
725             TCseconds = 0;
726             TCmoves = 50;
727         }
728         else
729         {
730             /* regular game */
731             char *q;
732             TCadd = 0;
733             TCmoves = (short)strtol(p, &q, 10);
734             TCminutes = (short)strtol(q, &q, 10);
735     
736             if (*q == ':')
737                 TCseconds = (short)strtol(q + 1, (char **) NULL, 10);
738             else
739                 TCseconds = 0;
740     
741     #ifdef OPERATORTIME
742             fputs("Operator time (hundredths) = ", stdout);
743             scanf("%hd", &OperatorTime);
744     #endif
745     
746             if (TCmoves == 0)
747             {
748                 TCflag = false;
749                 MaxResponseTime = TCminutes*60L * 100L + TCseconds * 100L;
750                 TCminutes = TCseconds = 0;
751             }
752             else
753             {
754                 TCflag = true;
755                 MaxResponseTime = 0;
756             }
757         }
758     } else {
759         int min, sec=0, inc, mps;
760         /* parse regular "level MPS TC INC" command of WB protocol */
761         if (sscanf(sx, "%d %d %d", &mps, &min, &inc) != 3)
762             sscanf(sx, "%d %d:%d %d", &mps, &min, &sec, &inc);
763         TCminutes = min; TCseconds = sec;
764         TCadd = inc*100; TCmoves = mps;
765         MaxResponseTime = 0; TCflag = true;
766         if (!mps) /* Fischer TC or sudden death */
767         {
768             TCmoves = 50;
769             TCflag = 2; /* kludge to requests special calculation of ResponseTime */
770         }
771     }
772
773     TimeControl.clock[black] = TimeControl.clock[white] = 0;
774     SetTimeControl();
775
776     if (XSHOGI)
777     {
778         printf("Clocks: %ld %ld\n",
779                TimeControl.clock[black] * 10,
780                TimeControl.clock[white] * 10);
781     }
782 }
783
784
785 static void
786 Raw_ChangeSearchDepth(char *sx)
787 {
788     char buf[80+1];
789     strncpy(buf, sx, 80); buf[80] = '\0';
790     /* if line empty, ask for input */
791     if (!buf[0]) {
792         printf("depth = ");
793         fgets(buf, 80+1, stdin);
794     }
795     sscanf(buf, "%hd", &MaxSearchDepth);
796     TCflag = !(MaxSearchDepth > 0);
797 }
798
799
800 static void
801 Raw_ChangeHashDepth(void)
802 {
803     printf("hashdepth = ");
804     scanf("%hd", &HashDepth);
805     printf("MoveLimit = ");
806     scanf("%hd", &HashMoveLimit);
807 }
808
809
810 static void
811 Raw_SetContempt(void)
812 {
813     printf("contempt = ");
814     scanf("%hd", &contempt);
815 }
816
817
818 static void
819 Raw_ChangeXwindow(void)
820 {
821     printf("xwndw = ");
822     scanf("%hd", &xwndw);
823 }
824
825
826 /*
827  * Raw_ShowPostnValue(short sq)
828  * must have called ExaminePosition() first
829  */
830 static void
831 Raw_ShowPostnValue(short sq)
832 {
833     (void) ScorePosition(color[sq]);
834
835     if (color[sq] != neutral)
836     {
837 #if defined SAVE_SVALUE
838         printf("???%c ", (color[sq] == white)?'b':'w');
839 #else
840         printf("%3d%c ", svalue[sq], (color[sq] == white)?'b':'w');
841 #endif
842     }
843     else
844     {
845         printf(" *   ");
846     }
847 }
848
849
850 static void
851 Raw_DoDebug(void)
852 {
853     short c, p, sq, tp, tc, tsq, score, j, k;
854     char s[40];
855
856     ExaminePosition(opponent);
857     Raw_ShowMessage("Enter piece: ");
858     scanf("%s", s);
859     c = neutral;
860
861     if ((s[0] == 'b') || (s[0] == 'B'))
862         c = black;
863
864     if ((s[0] == 'w') || (s[0] == 'W'))
865         c = white;
866
867     for (p = king; p > no_piece; p--)
868     {
869         if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
870             break;
871     }
872
873     if (p > no_piece)
874     {
875         for (j = (NO_ROWS - 1); j >= 0; j--)
876         {
877             for (k = 0; k < (NO_COLS); k++)
878             {
879                 sq = j*(NO_COLS) + k;
880                 tp = board[sq];
881                 tc = color[sq];
882                 board[sq] = p;
883                 color[sq] = c;
884                 tsq = PieceList[c][1];
885                 PieceList[c][1] = sq;
886                 Raw_ShowPostnValue(sq);
887                 PieceList[c][1] = tsq;
888                 board[sq] = tp;
889                 color[sq] = tc;
890             }
891
892             printf("\n");
893         }
894     }
895
896     score = ScorePosition(opponent);
897
898     for (j = (NO_ROWS - 1); j >= 0; j--)
899     {
900         for (k = 0; k < (NO_COLS); k++)
901         {
902             sq = j*(NO_COLS) + k;
903
904             if (color[sq] != neutral)
905             {
906 #if defined SAVE_SVALUE
907                 printf("%?????%c ", (color[sq] == white)?'b':'w');
908 #else
909                 printf("%5d%c ", svalue[sq], (color[sq] == white)?'b':'w');
910 #endif
911             }
912             else
913             {
914                 printf("    *  ");
915             }
916         }
917
918         printf("\n");
919     }
920
921     printf("stage = %d\n", stage);
922     printf("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
923            mtl[computer], pscore[computer], GameType[computer],
924            mtl[opponent], pscore[opponent], GameType[opponent]);
925 }
926
927
928 static void
929 Raw_DoTable(short table[NO_SQUARES])
930 {
931     short  sq, j, k;
932     ExaminePosition(opponent);
933
934     for (j = (NO_ROWS - 1); j >= 0; j--)
935     {
936         for (k = 0; k < NO_COLS; k++)
937         {
938             sq = j*(NO_ROWS) + k;
939             printf("%3d ", table[sq]);
940         }
941
942         printf("\n");
943     }
944 }
945
946
947 static void
948 Raw_ShowPostnValues(void)
949 {
950     short sq, score, j, k;
951     ExaminePosition(opponent);
952
953     for (j = (NO_ROWS - 1); j >= 0; j--)
954     {
955         for (k = 0; k < NO_COLS; k++)
956         {
957             sq = j * NO_COLS + k;
958             Raw_ShowPostnValue(sq);
959         }
960
961         printf("\n");
962     }
963
964     score = ScorePosition(opponent);
965     printf("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
966            mtl[computer], pscore[computer], GameType[computer],
967            mtl[opponent], pscore[opponent], GameType[opponent]);
968     printf("\nhung black %d hung white %d\n", hung[black], hung[white]);
969 }
970
971
972 static void
973 Raw_PollForInput(void)
974 {
975 #ifdef WIN32
976     DWORD cnt;
977     if (!PeekNamedPipe(GetStdHandle(STD_INPUT_HANDLE), NULL, 0, NULL, &cnt, NULL))
978         cnt = 1;
979 #else
980     static struct pollfd pollfds[1] = { [0] = { .fd = STDIN_FILENO,
981                                                 .events = POLLIN } };
982     int cnt = poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), 0);
983     if (cnt < 0) {
984         perror("polling standard input");
985         Raw_ExitShogi();
986     }
987 #endif
988     if (cnt && InputCommand(false)) { /* if anything to read, or error occured */
989         if (!flag.timeout)
990             flag.back = true; /* previous: flag.timeout = true; */
991         flag.bothsides = false;
992     }
993 }
994
995 struct display raw_display =
996 {
997     .ChangeAlphaWindow    = Raw_ChangeAlphaWindow,
998     .ChangeBetaWindow     = Raw_ChangeBetaWindow,
999     .ChangeHashDepth      = Raw_ChangeHashDepth,
1000     .ChangeSearchDepth    = Raw_ChangeSearchDepth,
1001     .ChangeXwindow        = Raw_ChangeXwindow,
1002     .ClearScreen          = Raw_ClearScreen,
1003     .DoDebug              = Raw_DoDebug,
1004     .DoTable              = Raw_DoTable,
1005     .EditBoard            = Raw_EditBoard,
1006     .ExitShogi            = Raw_ExitShogi,
1007     .GiveHint             = Raw_GiveHint,
1008     .Initialize           = Raw_Initialize,
1009     .ShowNodeCnt          = Raw_ShowNodeCnt,
1010     .OutputMove           = Raw_OutputMove,
1011     .PollForInput         = Raw_PollForInput,
1012     .SetContempt          = Raw_SetContempt,
1013     .SearchStartStuff     = Raw_SearchStartStuff,
1014     .SelectLevel          = Raw_SelectLevel,
1015     .ShowCurrentMove      = Raw_ShowCurrentMove,
1016     .ShowDepth            = Raw_ShowDepth,
1017     .ShowGameType         = Raw_ShowGameType,
1018     .ShowLine             = Raw_ShowLine,
1019     .ShowMessage          = Raw_ShowMessage,
1020     .AlwaysShowMessage    = Raw_AlwaysShowMessage,
1021     .Printf               = Raw_Printf,
1022     .doRequestInputString = Raw_doRequestInputString,
1023     .GetString            = Raw_GetString,
1024     .SetupBoard           = Raw_SetupBoard,
1025     .ShowPatternCount     = Raw_ShowPatternCount,
1026     .ShowPostnValue       = Raw_ShowPostnValue,
1027     .ShowPostnValues      = Raw_ShowPostnValues,
1028     .ShowPrompt           = Raw_ShowPrompt,
1029     .ShowResponseTime     = Raw_ShowResponseTime,
1030     .ShowResults          = Raw_ShowResults,
1031     .ShowSidetoMove       = Raw_ShowSidetoMove,
1032     .ShowStage            = Raw_ShowStage,
1033     .TerminateSearch      = Raw_TerminateSearch,
1034     .UpdateClocks         = Raw_UpdateClocks,
1035     .UpdateDisplay        = Raw_UpdateDisplay,
1036     .help                 = Raw_help,
1037 };