d9ebe36e016610d77dffc42522c4cb48aa418698
[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         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 ? mps : 50;
765         MaxResponseTime = 0; TCflag = true;
766     }
767
768     TimeControl.clock[black] = TimeControl.clock[white] = 0;
769     SetTimeControl();
770
771     if (XSHOGI)
772     {
773         printf("Clocks: %ld %ld\n",
774                TimeControl.clock[black] * 10,
775                TimeControl.clock[white] * 10);
776     }
777 }
778
779
780 static void
781 Raw_ChangeSearchDepth(char *sx)
782 {
783     char buf[80+1];
784     strncpy(buf, sx, 80); buf[80] = '\0';
785     /* if line empty, ask for input */
786     if (!buf[0]) {
787         printf("depth = ");
788         fgets(buf, 80+1, stdin);
789     }
790     sscanf(buf, "%hd", &MaxSearchDepth);
791     TCflag = !(MaxSearchDepth > 0);
792 }
793
794
795 static void
796 Raw_ChangeHashDepth(void)
797 {
798     printf("hashdepth = ");
799     scanf("%hd", &HashDepth);
800     printf("MoveLimit = ");
801     scanf("%hd", &HashMoveLimit);
802 }
803
804
805 static void
806 Raw_SetContempt(void)
807 {
808     printf("contempt = ");
809     scanf("%hd", &contempt);
810 }
811
812
813 static void
814 Raw_ChangeXwindow(void)
815 {
816     printf("xwndw = ");
817     scanf("%hd", &xwndw);
818 }
819
820
821 /*
822  * Raw_ShowPostnValue(short sq)
823  * must have called ExaminePosition() first
824  */
825 static void
826 Raw_ShowPostnValue(short sq)
827 {
828     (void) ScorePosition(color[sq]);
829
830     if (color[sq] != neutral)
831     {
832 #if defined SAVE_SVALUE
833         printf("???%c ", (color[sq] == white)?'b':'w');
834 #else
835         printf("%3d%c ", svalue[sq], (color[sq] == white)?'b':'w');
836 #endif
837     }
838     else
839     {
840         printf(" *   ");
841     }
842 }
843
844
845 static void
846 Raw_DoDebug(void)
847 {
848     short c, p, sq, tp, tc, tsq, score, j, k;
849     char s[40];
850
851     ExaminePosition(opponent);
852     Raw_ShowMessage("Enter piece: ");
853     scanf("%s", s);
854     c = neutral;
855
856     if ((s[0] == 'b') || (s[0] == 'B'))
857         c = black;
858
859     if ((s[0] == 'w') || (s[0] == 'W'))
860         c = white;
861
862     for (p = king; p > no_piece; p--)
863     {
864         if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
865             break;
866     }
867
868     if (p > no_piece)
869     {
870         for (j = (NO_ROWS - 1); j >= 0; j--)
871         {
872             for (k = 0; k < (NO_COLS); k++)
873             {
874                 sq = j*(NO_COLS) + k;
875                 tp = board[sq];
876                 tc = color[sq];
877                 board[sq] = p;
878                 color[sq] = c;
879                 tsq = PieceList[c][1];
880                 PieceList[c][1] = sq;
881                 Raw_ShowPostnValue(sq);
882                 PieceList[c][1] = tsq;
883                 board[sq] = tp;
884                 color[sq] = tc;
885             }
886
887             printf("\n");
888         }
889     }
890
891     score = ScorePosition(opponent);
892
893     for (j = (NO_ROWS - 1); j >= 0; j--)
894     {
895         for (k = 0; k < (NO_COLS); k++)
896         {
897             sq = j*(NO_COLS) + k;
898
899             if (color[sq] != neutral)
900             {
901 #if defined SAVE_SVALUE
902                 printf("%?????%c ", (color[sq] == white)?'b':'w');
903 #else
904                 printf("%5d%c ", svalue[sq], (color[sq] == white)?'b':'w');
905 #endif
906             }
907             else
908             {
909                 printf("    *  ");
910             }
911         }
912
913         printf("\n");
914     }
915
916     printf("stage = %d\n", stage);
917     printf("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
918            mtl[computer], pscore[computer], GameType[computer],
919            mtl[opponent], pscore[opponent], GameType[opponent]);
920 }
921
922
923 static void
924 Raw_DoTable(short table[NO_SQUARES])
925 {
926     short  sq, j, k;
927     ExaminePosition(opponent);
928
929     for (j = (NO_ROWS - 1); j >= 0; j--)
930     {
931         for (k = 0; k < NO_COLS; k++)
932         {
933             sq = j*(NO_ROWS) + k;
934             printf("%3d ", table[sq]);
935         }
936
937         printf("\n");
938     }
939 }
940
941
942 static void
943 Raw_ShowPostnValues(void)
944 {
945     short sq, score, j, k;
946     ExaminePosition(opponent);
947
948     for (j = (NO_ROWS - 1); j >= 0; j--)
949     {
950         for (k = 0; k < NO_COLS; k++)
951         {
952             sq = j * NO_COLS + k;
953             Raw_ShowPostnValue(sq);
954         }
955
956         printf("\n");
957     }
958
959     score = ScorePosition(opponent);
960     printf("S%d m%d ps%d gt%c m%d ps%d gt%c", score,
961            mtl[computer], pscore[computer], GameType[computer],
962            mtl[opponent], pscore[opponent], GameType[opponent]);
963     printf("\nhung black %d hung white %d\n", hung[black], hung[white]);
964 }
965
966
967 static void
968 Raw_PollForInput(void)
969 {
970 #ifdef WIN32
971     DWORD cnt;
972     if (!PeekNamedPipe(GetStdHandle(STD_INPUT_HANDLE), NULL, 0, NULL, &cnt, NULL))
973         cnt = 1;
974 #else
975     static struct pollfd pollfds[1] = { [0] = { .fd = STDIN_FILENO,
976                                                 .events = POLLIN } };
977     int cnt = poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), 0);
978     if (cnt < 0) {
979         perror("polling standard input");
980         Raw_ExitShogi();
981     }
982 #endif
983     if (cnt) { /* if anything to read, or error occured */
984         if (!flag.timeout)
985             flag.back = true; /* previous: flag.timeout = true; */
986         flag.bothsides = false;
987     }
988 }
989
990 struct display raw_display =
991 {
992     .ChangeAlphaWindow    = Raw_ChangeAlphaWindow,
993     .ChangeBetaWindow     = Raw_ChangeBetaWindow,
994     .ChangeHashDepth      = Raw_ChangeHashDepth,
995     .ChangeSearchDepth    = Raw_ChangeSearchDepth,
996     .ChangeXwindow        = Raw_ChangeXwindow,
997     .ClearScreen          = Raw_ClearScreen,
998     .DoDebug              = Raw_DoDebug,
999     .DoTable              = Raw_DoTable,
1000     .EditBoard            = Raw_EditBoard,
1001     .ExitShogi            = Raw_ExitShogi,
1002     .GiveHint             = Raw_GiveHint,
1003     .Initialize           = Raw_Initialize,
1004     .ShowNodeCnt          = Raw_ShowNodeCnt,
1005     .OutputMove           = Raw_OutputMove,
1006     .PollForInput         = Raw_PollForInput,
1007     .SetContempt          = Raw_SetContempt,
1008     .SearchStartStuff     = Raw_SearchStartStuff,
1009     .SelectLevel          = Raw_SelectLevel,
1010     .ShowCurrentMove      = Raw_ShowCurrentMove,
1011     .ShowDepth            = Raw_ShowDepth,
1012     .ShowGameType         = Raw_ShowGameType,
1013     .ShowLine             = Raw_ShowLine,
1014     .ShowMessage          = Raw_ShowMessage,
1015     .AlwaysShowMessage    = Raw_AlwaysShowMessage,
1016     .Printf               = Raw_Printf,
1017     .doRequestInputString = Raw_doRequestInputString,
1018     .GetString            = Raw_GetString,
1019     .SetupBoard           = Raw_SetupBoard,
1020     .ShowPatternCount     = Raw_ShowPatternCount,
1021     .ShowPostnValue       = Raw_ShowPostnValue,
1022     .ShowPostnValues      = Raw_ShowPostnValues,
1023     .ShowPrompt           = Raw_ShowPrompt,
1024     .ShowResponseTime     = Raw_ShowResponseTime,
1025     .ShowResults          = Raw_ShowResults,
1026     .ShowSidetoMove       = Raw_ShowSidetoMove,
1027     .ShowStage            = Raw_ShowStage,
1028     .TerminateSearch      = Raw_TerminateSearch,
1029     .UpdateClocks         = Raw_UpdateClocks,
1030     .UpdateDisplay        = Raw_UpdateDisplay,
1031     .help                 = Raw_help,
1032 };