GNU Shogi 1.2p01
[gnushogi.git] / src / dspcom.c
blob43764adc578d12c1008534129fd470ed8295d4ce
1 /*
2 * dspcom.c - C source for GNU SHOGI
4 * Copyright (c) 1993, 1994 Matthias Mutz
6 * GNU SHOGI is based on GNU CHESS
8 * Copyright (c) 1988,1989,1990 John Stanback
9 * Copyright (c) 1992 Free Software Foundation
11 * This file is part of GNU SHOGI.
13 * GNU Shogi is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 1, or (at your option)
16 * any later version.
18 * GNU Shogi is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with GNU Shogi; see the file COPYING. If not, write to
25 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include "gnushogi.h"
30 #if defined HASGETTIMEOFDAY
31 #include <sys/time.h>
32 #endif
33 char mvstr[4][6];
34 char *InPtr;
35 int InBackground = false;
38 #include <ctype.h>
39 #include <signal.h>
40 #if defined THINK_C
41 #include <time.h>
42 #define BOOKTEST
43 #elif defined MSDOS
44 #include <dos.h>
45 #include <conio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h>
49 #else
50 #include <sys/param.h>
51 #include <sys/types.h>
52 #include <sys/file.h>
53 #include <sys/ioctl.h>
54 #endif
56 #if defined DEBUG || defined DEBUG_EVAL
57 short debug_eval = false;
58 FILE *debug_eval_file = NULL;
59 short debug_moves = false;
60 #endif
63 #if defined DEBUG || defined BOOKTEST || defined DEBUG_EVAL
65 void
66 movealgbr (short int m, char *s)
68 unsigned int f, t;
69 short piece = 0, flag = 0;
70 if ( m == 0 )
72 strcpy(s,"none");
73 return;
75 f = (m >> 8) & 0x7f;
76 t = m & 0xff;
77 if ( f > NO_SQUARES )
78 { piece = f - NO_SQUARES;
79 if ( piece > NO_PIECES ) piece -= NO_PIECES;
80 flag = (dropmask | piece);
82 if ( t & 0x80 )
84 flag |= promote;
85 t &= 0x7f;
87 if ( flag & dropmask )
89 *s = pxx[piece]; s++;
90 *s = '*'; s++;
91 *s = cxx[column (t)]; s++;
92 *s = rxx[row (t)]; s++;
94 else
96 *s = cxx[column (f)]; s++;
97 *s = rxx[row (f)]; s++;
98 *s = cxx[column (t)]; s++;
99 *s = rxx[row (t)]; s++;
100 if ( flag & promote )
102 *s = '+'; s++;
105 if (m & 0x8000)
107 *s = '?'; s++;
109 *s = '\0';
112 #endif
115 void
116 algbr (short int f, short int t, short int flag)
120 * Generate move strings in different formats.
124 int m3p;
126 if ( f > NO_SQUARES )
127 { short piece;
128 piece = f - NO_SQUARES;
129 if ( f > (NO_SQUARES+NO_PIECES) )
130 piece -= NO_PIECES;
131 flag = (dropmask | piece);
133 if ( (t & 0x80) != 0 )
135 flag |= promote;
136 t &= 0x7f;
138 if ( f == t && (f != 0 || t != 0) )
140 #if !defined BAREBONES
141 printz("error in algbr: FROM=TO=%d, flag=0x%4x\n",t,flag);
142 #endif
143 mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
145 else
146 if ( (flag & dropmask) != 0 )
147 { short piece = flag & pmask;
148 mvstr[0][0] = pxx[piece];
149 mvstr[0][1] = '*';
150 mvstr[0][2] = cxx[column (t)];
151 mvstr[0][3] = rxx[row (t)];
152 mvstr[0][4] = '\0';
153 strcpy (mvstr[1], mvstr[0]);
154 strcpy (mvstr[2], mvstr[0]);
155 strcpy (mvstr[3], mvstr[0]);
157 else
158 if (f != 0 || t != 0)
160 /* algebraic notation */
161 mvstr[0][0] = cxx[column (f)];
162 mvstr[0][1] = rxx[row (f)];
163 mvstr[0][2] = cxx[column (t)];
164 mvstr[0][3] = rxx[row (t)];
165 mvstr[0][4] = mvstr[3][0] = '\0';
166 mvstr[1][0] = pxx[board[f]];
168 mvstr[2][0] = mvstr[1][0];
169 mvstr[2][1] = mvstr[0][1];
171 mvstr[2][2] = mvstr[1][1] = mvstr[0][2]; /* to column */
172 mvstr[2][3] = mvstr[1][2] = mvstr[0][3]; /* to row */
173 mvstr[2][4] = mvstr[1][3] = '\0';
174 strcpy (mvstr[3], mvstr[2]);
175 mvstr[3][1] = mvstr[0][0];
176 if (flag & promote)
178 strcat(mvstr[0], "+");
179 strcat(mvstr[1], "+");
180 strcat(mvstr[2], "+");
181 strcat(mvstr[3], "+");
184 else
185 mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
190 VerifyMove (char *s, VerifyMove_mode iop, short unsigned int *mv)
193 * Compare the string 's' to the list of legal moves available for the
194 * opponent. If a match is found, make the move on the board.
198 static short pnt, tempb, tempc, tempsf, tempst, cnt;
199 static struct leaf xnode;
200 struct leaf far *node;
201 char buffer[60],buf2[60];
202 short i,l, local_flags;
204 /* check and remove quality flags */
205 for (i=local_flags=0,l=strlen(s); i<l; i++)
206 switch (s[i]) {
207 case '?' : local_flags |= badmove; s[i]='\0'; break;
208 case '!' : local_flags |= goodmove; s[i]='\0'; break;
209 #ifdef EASY_OPENINGS
210 case '~' : local_flags |= difficult; s[i]='\0'; break;
211 #endif
214 *mv = 0;
215 if (iop == UNMAKE_MODE)
217 UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
218 return (false);
220 cnt = 0;
221 if (iop == VERIFY_AND_MAKE_MODE)
222 generate_move_flags = true;
223 MoveList (opponent, 2, -1, true);
224 generate_move_flags = false;
225 pnt = TrPnt[2];
226 while (pnt < TrPnt[3])
228 node = &Tree[pnt++];
229 algbr (node->f, node->t, (short) node->flags);
230 if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
231 strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
233 cnt++;
234 xnode = *node;
237 if (cnt == 1 && xnode.score > DONTUSE)
239 short blocked;
240 MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
241 if (SqAtakd (PieceList[opponent][0], computer, &blocked))
243 UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
244 #ifdef NONDSP
245 /* Illegal move in check */
246 printz (CP[77],mvstr[0]);
247 printz ("\n");
248 #else
249 /* Illegal move in check */
250 sprintf (buffer, CP[77], s);
251 ShowMessage (buffer);
252 #endif
253 return (false);
255 else
257 if (iop == VERIFY_AND_TRY_MODE)
258 return (true);
259 UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
260 GameList[GameCnt].depth = GameList[GameCnt].score = 0;
261 GameList[GameCnt].nodes = 0;
262 ElapsedTime (COMPUTE_AND_INIT_MODE);
263 GameList[GameCnt].time = (short) (et+50)/100;
264 GameList[GameCnt].flags |= local_flags;
265 if (TCflag)
267 TimeControl.clock[opponent] -= et;
268 timeopp[oppptr] = et;
269 --TimeControl.moves[opponent];
271 *mv = (xnode.f << 8) | xnode.t;
272 algbr (xnode.f, xnode.t, false);
273 /* in force mode, check for mate conditions */
274 if ( flag.force )
276 if ( IsCheckmate(opponent ^ 1,-1,-1) )
277 { char buf[20],buf2[20];
278 sprintf(buf,"%s mates!\n",ColorStr[opponent]);
279 ShowMessage(buf);
280 flag.mate = true;
283 return (true);
286 #ifdef NONDSP
287 /* Illegal move */
288 printz (CP[75], s);
289 #ifdef DEBUG8
290 if (1)
292 FILE *D;
293 int r, c, side, l;
294 extern unsigned short int PrVar[];
295 D = fopen ("/tmp/DEBUG", "a+");
296 pnt = TrPnt[2];
297 fprintf (D, "resp = %d\n", ResponseTime);
298 fprintf (D, "iop = %d\n", iop);
299 fprintf (D, "matches = %d\n", cnt);
300 algbr (hint >> 8, hint & 0xff, (short) 0);
301 fprintf (D, "hint %s\n", mvstr[0]);
302 fprintf (D, "inout move is %s\n", s);
303 for (r = 1; PrVar[r]; r++)
305 algbr (PrVar[r] >> 8, PrVar[r] & 0xff, (short) 0);
306 fprintf (D, " %s", mvstr[0]);
308 fprintf (D, "\n");
309 fprintf (D, "legal move are \n");
310 while (pnt < TrPnt[3])
312 node = &Tree[pnt++];
313 algbr (node->f, node->t, (short) node->flags);
314 fprintf (D, "%s %s %s %s\n", mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
316 debug_position (D);
317 fclose (D);
318 abort ();
320 #endif
321 #else
322 /* Illegal move */
323 sprintf(buffer,CP[76],s);
324 ShowMessage (buffer);
325 #endif
326 #if !defined BAREBONES
327 if (cnt > 1) {
328 sprintf(buffer,CP[32],s);
329 ShowMessage(buffer);
331 #endif
332 return (false);
337 static int
338 parser (char *f, int side, short *fpiece)
340 int c1, r1, c2, r2;
341 short i, p = false;
342 if ( *f == '+' )
343 f++, p = true;
344 for ( i = 1, *fpiece = no_piece; i<NO_PIECES; i++ )
345 if ( f[0] == pxx[i] || f[0] == qxx[i] )
347 *fpiece = (p ? promoted[i] : unpromoted[i]);
348 break;
350 if ( f[1] == '*' || f[1] == '\'' )
352 c2 = '9' - f[2];
353 r2 = 'i' - f[3];
354 return ((NO_SQUARES + *fpiece) << 8) | locn (r2, c2);
356 else
358 c1 = '9' - f[1];
359 r1 = 'i' - f[2];
360 c2 = '9' - f[3];
361 r2 = 'i' - f[4];
362 p = (f[5] == '+') ? 0x80 : 0;
363 return (locn (r1, c1) << 8) | locn (r2, c2) | p;
368 void
369 skip ()
371 while (*InPtr != ' ')
372 InPtr++;
373 while (*InPtr == ' ')
374 InPtr++;
377 void
378 skipb ()
380 while (*InPtr == ' ')
381 InPtr++;
386 void
387 GetGame (void)
389 FILE *fd;
390 char fname[256], *p;
391 int c, i, j;
392 short sq;
393 short side, isp;
394 if (savefile[0])
395 strcpy (fname, savefile);
396 else
398 /* Enter file name*/
399 ShowMessage (CP[63]);
400 scanz ("%s", fname);
402 /* shogi.000 */
403 if (fname[0] == '\0')
404 strcpy (fname, CP[137]);
405 if ((fd = fopen (fname, "r")) != NULL)
407 NewGame ();
408 fgets (fname, 256, fd);
409 computer = opponent = black;
410 InPtr = fname;
411 skip ();
412 if (*InPtr == 'c')
413 computer = white;
414 else
415 opponent = white;
416 skip ();
417 skip ();
418 skip ();
419 Game50 = atoi (InPtr);
420 skip ();
421 flag.force = (*InPtr == 'f');
422 fgets (fname, 256, fd); /* empty */
423 fgets (fname, 256, fd);
424 InPtr = &fname[11];
425 skipb ();
426 TCflag = atoi (InPtr);
427 skip ();
428 InPtr += 14;
429 skipb ();
430 OperatorTime = atoi (InPtr);
431 fgets (fname, 256, fd);
432 InPtr = &fname[11];
433 skipb ();
434 TimeControl.clock[black] = atol (InPtr);
435 skip ();
436 skip ();
437 TimeControl.moves[black] = atoi (InPtr);
438 fgets (fname, 256, fd);
439 InPtr = &fname[11];
440 skipb ();
441 TimeControl.clock[white] = atol (InPtr);
442 skip ();
443 skip ();
444 TimeControl.moves[white] = atoi (InPtr);
445 fgets (fname, 256, fd); /* empty */
446 for (i = NO_ROWS-1; i > -1; i--)
448 fgets (fname, 256, fd);
449 p = &fname[2];
450 InPtr = &fname[23];
451 for (j = 0; j < NO_COLS; j++)
453 sq = i * NO_COLS + j;
454 isp = ( *p == '+' );
455 p++;
456 if (*p == '-')
458 board[sq] = no_piece;
459 color[sq] = neutral;
461 else
463 for (c = 0; c < NO_PIECES; c++)
465 if (*p == pxx[c])
467 if ( isp )
468 board[sq] = promoted[c];
469 else
470 board[sq] = unpromoted[c];
471 color[sq] = white;
474 for (c = 0; c < NO_PIECES; c++)
476 if (*p == qxx[c])
478 if ( isp )
479 board[sq] = promoted[c];
480 else
481 board[sq] = unpromoted[c];
482 color[sq] = black;
486 p++;
487 Mvboard[sq] = atoi (InPtr);
488 skip ();
491 fgets (fname, 256, fd); /* empty */
492 fgets (fname, 256, fd); /* 9 8 7 ... */
493 fgets (fname, 256, fd); /* empty */
494 fgets (fname, 256, fd); /* p l n ... */
495 ClearCaptured ();
496 for ( side = 0; side <= 1; side++ ) {
497 fgets (fname, 256, fd);
498 InPtr = fname;
499 skip ();
500 skipb ();
501 Captured[side][pawn] = atoi (InPtr);
502 skip ();
503 Captured[side][lance] = atoi (InPtr);
504 skip ();
505 Captured[side][knight] = atoi (InPtr);
506 skip ();
507 Captured[side][silver] = atoi (InPtr);
508 skip ();
509 Captured[side][gold] = atoi (InPtr);
510 skip ();
511 Captured[side][bishop] = atoi (InPtr);
512 skip ();
513 Captured[side][rook] = atoi (InPtr);
514 skip ();
515 Captured[side][king] = atoi (InPtr);
517 GameCnt = 0;
518 flag.regularstart = true;
519 Book = BOOKFAIL;
520 fgets (fname, 256, fd); /* empty */
521 fgets (fname, 256, fd); /* move score ... */
522 while (fgets (fname, 256, fd))
524 struct GameRec far *g;
525 int side = computer;
526 short f;
528 side = side ^ 1;
529 ++GameCnt;
530 InPtr = fname;
531 skipb ();
532 g = &GameList[GameCnt];
533 g->gmove = parser (InPtr, side, &g->fpiece);
534 skip ();
535 g->score = atoi (InPtr);
536 skip ();
537 g->depth = atoi (InPtr);
538 skip ();
539 g->nodes = atol (InPtr);
540 skip ();
541 g->time = atol (InPtr);
542 skip ();
543 g->flags = c = atoi (InPtr);
544 skip ();
545 g->hashkey = strtol (InPtr, (char **) NULL, 16);
546 skip ();
547 g->hashbd = strtol (InPtr, (char **) NULL, 16);
548 if (c & capture)
549 { short i, piece;
551 skip ();
552 for (piece = no_piece, i = 0; i < NO_PIECES; i++)
553 if (pxx[i] == *InPtr) {
554 piece = i;
555 break;
557 skip ();
558 g->color = ((*InPtr == CP[119][0]) ? white : black);
559 skip ();
560 g->piece = (*InPtr == '+' ? promoted[piece] : unpromoted[piece]);
562 else
564 g->color = neutral;
565 g->piece = no_piece;
568 if (TimeControl.clock[black] > 0)
569 TCflag = true;
570 fclose (fd);
572 ZeroRPT ();
573 InitializeStats ();
574 UpdateDisplay (0, 0, 1, 0);
575 Sdepth = 0;
576 hint = 0;
580 #if !defined XSHOGI
583 void
584 GetXGame (void)
586 FILE *fd;
587 char fname[256], *p;
588 int c, i, j;
589 short sq;
590 short side, isp;
591 /* Enter file name */
592 ShowMessage (CP[63]);
593 scanz ("%s", fname);
594 if (fname[0] == '\0')
595 /* XSHOGI.position.read*/
596 strcpy (fname, CP[205]);
597 if ((fd = fopen (fname, "r")) != NULL)
599 NewGame ();
600 flag.regularstart = false;
601 Book = false;
602 /* xshogi position file ... */
603 fgets (fname, 256, fd);
604 #ifdef notdef
605 fname[6] = '\0';
606 if (strcmp (fname, CP[206]))
607 return;
608 #endif
609 /* -- empty line -- */
610 fgets (fname, 256, fd);
611 /* -- empty line -- */
612 fgets (fname, 256, fd);
613 for (i = NO_ROWS-1; i > -1; i--)
615 fgets (fname, 256, fd);
616 p = fname;
617 for (j = 0; j < NO_COLS; j++)
619 sq = i * NO_COLS + j;
620 isp = ( *p == '+' );
621 p++;
622 if (*p == '.')
624 board[sq] = no_piece;
625 color[sq] = neutral;
627 else
629 for (c = 0; c < NO_PIECES; c++)
631 if (*p == qxx[c])
633 if ( isp )
634 board[sq] = promoted[c];
635 else
636 board[sq] = unpromoted[c];
637 color[sq] = white;
640 for (c = 0; c < NO_PIECES; c++)
642 if (*p == pxx[c])
644 if ( isp )
645 board[sq] = promoted[c];
646 else
647 board[sq] = unpromoted[c];
648 color[sq] = black;
652 p++;
655 ClearCaptured ();
656 for ( side = 0; side <= 1; side++ ) {
657 fgets (fname, 256, fd);
658 InPtr = fname;
659 Captured[side][pawn] = atoi (InPtr);
660 skip ();
661 Captured[side][lance] = atoi (InPtr);
662 skip ();
663 Captured[side][knight] = atoi (InPtr);
664 skip ();
665 Captured[side][silver] = atoi (InPtr);
666 skip ();
667 Captured[side][gold] = atoi (InPtr);
668 skip ();
669 Captured[side][bishop] = atoi (InPtr);
670 skip ();
671 Captured[side][rook] = atoi (InPtr);
672 skip ();
673 Captured[side][king] = atoi (InPtr);
675 if (fgets(fname, 256, fd) != NULL && strncmp(fname, "white", 5) == 0)
677 computer = black;
678 opponent = white;
679 xwndw = BXWNDW;
681 fclose (fd);
683 Game50 = 1;
684 ZeroRPT ();
685 InitializeStats ();
686 UpdateDisplay (0, 0, 1, 0);
687 Sdepth = 0;
688 hint = 0;
692 void
693 SaveXGame (void)
695 FILE *fd;
696 char fname[256], *p;
697 int c, i, j;
698 short sq, piece;
699 short side, isp;
700 /* Enter file name */
701 ShowMessage (CP[63]);
702 scanz ("%s", fname);
703 if (fname[0] == '\0')
704 /* XSHOGI.position.read*/
705 strcpy (fname, CP[205]);
706 if ((fd = fopen (fname, "w")) != NULL)
708 /* xshogi position file ... */
709 fputs("# xshogi position file -- \n", fd);
710 /* -- empty line -- */
711 fputs("\n",fd);
712 /* -- empty line -- */
713 fputs("\n", fd);
714 for (i = NO_ROWS-1; i > -1; i--)
716 p = fname;
717 for (j = 0; j < NO_COLS; j++)
719 sq = i * NO_COLS + j;
720 piece = board[sq];
721 isp = is_promoted[piece];
722 *p = (isp ? '+' : ' ');
723 p++;
724 if ( piece == no_piece ) {
725 *p = '.';
726 } else if ( color[sq] == white ) {
727 *p = qxx[piece];
728 } else {
729 *p = pxx[piece];
731 p++;
733 *p++ = '\n';;
734 *p++ = '\0';;
735 fputs(fname, fd);
737 for ( side = 0; side <= 1; side++ ) {
738 sprintf(fname,"%d %d %d %d %d %d %d %d\n",
739 Captured[side][pawn],
740 Captured[side][lance],
741 Captured[side][knight],
742 Captured[side][silver],
743 Captured[side][gold],
744 Captured[side][bishop],
745 Captured[side][rook],
746 Captured[side][king]);
747 fputs(fname, fd);
749 if ( computer == black ) {
750 fputs("white to play\n", fd);
751 } else {
752 fputs("black to play\n", fd);
754 fclose (fd);
760 #endif /* !XSHOGI */
763 void
764 SaveGame (void)
766 FILE *fd;
767 char fname[256];
768 short sq, i, c, f, t;
769 char p;
770 short side, piece;
771 char empty[2] = "\n";
773 if (savefile[0])
774 strcpy (fname, savefile);
775 else
777 /* Enter file name*/
778 ShowMessage (CP[63]);
779 scanz ("%s", fname);
781 if (fname[0] == '\0')
782 /* shogi.000 */
783 strcpy (fname, CP[137]);
784 if ((fd = fopen (fname, "w")) != NULL)
786 char *b, *w;
787 b = w = CP[74];
788 if (computer == white)
789 w = CP[141];
790 if (computer == black)
791 b = CP[141];
792 fprintf (fd, CP[37], w, b, Game50,
793 flag.force ? "force" : "");
794 fprintf (fd, empty);
795 fprintf (fd, CP[111], TCflag, OperatorTime);
796 fprintf (fd, CP[117],
797 TimeControl.clock[black], TimeControl.moves[black],
798 TimeControl.clock[white], TimeControl.moves[white]);
799 fprintf (fd, empty);
800 for (i = NO_ROWS-1; i > -1; i--)
802 fprintf (fd, "%c ", 'i' - i);
803 for (c = 0; c < NO_COLS; c++)
805 sq = i * NO_COLS + c;
806 piece = board[sq];
807 p = is_promoted[piece] ? '+' : ' ';
808 fprintf (fd, "%c", p);
809 switch (color[sq])
811 case white:
812 p = pxx[piece];
813 break;
814 case black:
815 p = qxx[piece];
816 break;
817 default:
818 p = '-';
820 fprintf (fd, "%c", p);
822 fprintf (fd, " ");
823 for (f = i * NO_COLS; f < i * NO_COLS + NO_ROWS; f++)
824 fprintf (fd, " %d", Mvboard[f]);
825 fprintf (fd, "\n");
827 fprintf (fd, empty);
828 fprintf (fd, " 9 8 7 6 5 4 3 2 1\n");
829 fprintf (fd, empty);
830 fprintf (fd, " p l n s g b r k\n");
831 for ( side = 0; side <= 1; side++ ) {
832 fprintf (fd, "%c", (side == black) ? 'B' : 'W');
833 fprintf (fd, " %2d", Captured[side][pawn]);
834 fprintf (fd, " %2d", Captured[side][lance]);
835 fprintf (fd, " %2d", Captured[side][knight]);
836 fprintf (fd, " %2d", Captured[side][silver]);
837 fprintf (fd, " %2d", Captured[side][gold]);
838 fprintf (fd, " %2d", Captured[side][bishop]);
839 fprintf (fd, " %2d", Captured[side][rook]);
840 fprintf (fd, " %2d", Captured[side][king]);
841 fprintf (fd, "\n");
843 fprintf (fd, empty);
844 fprintf (fd, CP[126]);
845 for (i = 1; i <= GameCnt; i++)
847 struct GameRec far *g = &GameList[i];
849 f = g->gmove >> 8;
850 t = (g->gmove & 0xFF);
851 algbr (f, t, g->flags);
852 #ifdef THINK_C
853 fprintf (fd, "%c%c%-5s %6d %5d %7ld %6ld %5d 0x%08lx 0x%08lx",
854 #else
855 fprintf (fd, "%c%c%-5s %6d %5d %7ld %6ld %5d 0x%08x 0x%08x",
856 #endif
857 (f>NO_SQUARES ? ' ' : (is_promoted[g->fpiece] ? '+' : ' ')),
858 pxx[g->fpiece],
859 (f>NO_SQUARES ? &mvstr[0][1] : mvstr[0]),
860 g->score, g->depth,
861 g->nodes, g->time, g->flags,
862 g->hashkey, g->hashbd);
863 if ( g->piece != no_piece )
864 fprintf (fd, " %c %s %c\n",
865 pxx[g->piece], ColorStr[g->color],
866 (is_promoted[g->piece] ? '+' : ' '));
867 else
868 fprintf (fd, "\n");
870 fclose (fd);
871 /* Game saved */
872 ShowMessage (CP[70]);
874 else
875 /*ShowMessage ("Could not open file");*/
876 ShowMessage (CP[48]);
881 #if !defined XSHOGI
884 void
885 BookSave (void)
887 FILE *fd;
888 char fname[256], sflags[4];
889 short sq, i, j, c, f, t;
890 char p;
891 short side, piece;
893 if (savefile[0])
894 strcpy (fname, savefile);
895 else
897 /* Enter file name*/
898 ShowMessage (CP[63]);
899 scanz ("%s", fname);
902 if (fname[0] == '\0')
903 return;
905 if ((fd = fopen (fname, "a")) != NULL)
907 fprintf(fd,"#\n");
908 for (i = 1; i <= GameCnt; i++)
910 struct GameRec far *g = &GameList[i];
911 char mvnr[20], mvs[20];
912 if (i % 2)
913 sprintf(mvnr,"%d.",(i+1)/2);
914 else
915 strcpy(mvnr,"");
916 f = g->gmove >> 8;
917 t = (g->gmove & 0xFF);
918 algbr (f, t, g->flags);
919 j = 0;
920 /* determine move quality string */
921 if ( g->flags & goodmove )
922 sflags[j++] = '!';
923 if ( g->flags & badmove )
924 sflags[j++] = '?';
925 #ifdef EASY_OPENINGS
926 if ( g->flags & difficult )
927 sflags[j++] = '~';
928 #endif
929 sflags[j] = '\0';
930 /* determine move string */
931 if ( f>NO_SQUARES )
932 sprintf(mvs,"%s%s ",&mvstr[0][1],sflags);
933 else
934 sprintf(mvs,"%c%c%c%c%c%s%s ",
935 mvstr[0][0], mvstr[0][1],
936 (g->flags & capture) ? 'x' : '-',
937 mvstr[0][2], mvstr[0][3],
938 (mvstr[0][4]=='+') ? "+" : "",
939 sflags);
940 fprintf (fd, "%s%s%c%s",
941 mvnr,
942 (f>NO_SQUARES ? "" : (is_promoted[g->fpiece] ? "+" : "")),
943 pxx[g->fpiece],
944 mvs);
945 if ( (i % 10) == 0)
946 fprintf (fd, "\n");
948 if ( (i % 10) != 1)
949 fprintf (fd, "\n");
950 fclose (fd);
951 /* Game saved */
952 ShowMessage (CP[70]);
954 else
955 /*ShowMessage ("Could not open file");*/
956 ShowMessage (CP[48]);
960 #endif /* !XSHOGI */
963 void
964 ListGame (void)
966 FILE *fd;
967 short i, f, t;
968 #ifndef MSDOS
969 time_t when;
970 char fname[256], dbuf[256];
971 #else
972 char fname[256];
973 #endif
975 if (listfile[0])
976 strcpy (fname, listfile);
977 else
979 #ifdef MSDOS
980 sprintf (fname, "shogi.lst");
981 #else
982 time (&when);
983 strncpy (dbuf, ctime (&when), 20);
984 dbuf[7] = '\0';
985 dbuf[10] = '\0';
986 dbuf[13] = '\0';
987 dbuf[16] = '\0';
988 dbuf[19] = '\0';
989 /* use format "CLp16.Jan01-020304B" when patchlevel is 16,
990 date is Jan 1
991 time is 02:03:04
992 program played white */
993 sprintf (fname, "CLp%s.%s%s-%s%s%s%c", patchlevel, dbuf + 4, dbuf + 8, dbuf + 11, dbuf + 14, dbuf + 17, ColorStr[computer][0]);
994 /* replace space padding with 0 */
995 for (i = 0; fname[i] != '\0'; i++)
996 if (fname[i] == ' ')
997 fname[i] = '0';
998 #endif /* MSDOS */
1000 fd = fopen (fname, "w");
1001 if (!fd)
1003 printf (CP[219], fname);
1004 exit (1);
1006 /*fprintf (fd, "gnushogi game %d\n", u);*/
1007 fprintf (fd, CP[161], version, patchlevel);
1008 fprintf (fd, CP[10]);
1009 fprintf (fd, CP[11]);
1010 for (i = 1; i <= GameCnt; i++)
1012 f = GameList[i].gmove >> 8;
1013 t = (GameList[i].gmove & 0xFF);
1014 algbr (f, t, GameList[i].flags);
1015 if(GameList[i].flags & book)
1016 fprintf (fd, "%c%c%-5s %5d Book%7ld %5d",
1017 (f>NO_SQUARES ? ' ' : (is_promoted[GameList[i].fpiece] ? '+' : ' ')),
1018 pxx[GameList[i].fpiece],
1019 (f>NO_SQUARES ? &mvstr[0][1] : mvstr[0]),
1020 GameList[i].score,
1021 GameList[i].nodes, GameList[i].time);
1022 else
1023 fprintf (fd, "%c%c%-5s %5d %2d %7ld %5d",
1024 (f>NO_SQUARES ? ' ' : (is_promoted[GameList[i].fpiece] ? '+' : ' ')),
1025 pxx[GameList[i].fpiece],
1026 (f>NO_SQUARES ? &mvstr[0][1] : mvstr[0]),
1027 GameList[i].score, GameList[i].depth,
1028 GameList[i].nodes, GameList[i].time);
1029 if ((i % 2) == 0)
1031 fprintf (fd, "\n");
1032 #ifdef DEBUG40
1033 if (computer == white)
1034 fprintf (fd, " %d %d %d %d %d %d %d\n",
1035 GameList[i].d1,
1036 GameList[i].d2,
1037 GameList[i].d3,
1038 GameList[i].d4,
1039 GameList[i].d5,
1040 GameList[i].d6,
1041 GameList[i].d7);
1042 else
1043 fprintf (fd, " %d %d %d %d %d %d %d\n",
1044 GameList[i - 1].d1,
1045 GameList[i - 1].d2,
1046 GameList[i - 1].d3,
1047 GameList[i - 1].d4,
1048 GameList[i - 1].d5,
1049 GameList[i - 1].d6,
1050 GameList[i - 1].d7);
1051 #endif
1053 else
1054 fprintf (fd, " ");
1056 fprintf (fd, "\n\n");
1057 if (GameList[GameCnt].flags & draw)
1059 fprintf (fd, CP[54], DRAW);
1060 if ( DRAW == CP[101] )
1061 { short j;
1062 fprintf (fd, "repetition by positions ");
1063 for ( j = GameCnt-1; j >= Game50; j -= 2)
1064 if ( GameList[j].hashkey == hashkey &&
1065 GameList[j].hashbd == hashbd )
1066 fprintf (fd, "%d ", j);
1067 fprintf (fd, "\n");
1070 else if (GameList[GameCnt].score == -(SCORE_LIMIT+999))
1072 fprintf (fd, "%s\n", ColorStr[player ]);
1074 else if (GameList[GameCnt].score == (SCORE_LIMIT+998))
1076 fprintf (fd, "%s\n", ColorStr[player ^ 1]);
1078 fclose (fd);
1083 void
1084 FlagMove (char c)
1086 switch (c) {
1087 case '?' :
1088 GameList[GameCnt].flags |= badmove;
1089 break;
1090 case '!' :
1091 GameList[GameCnt].flags |= goodmove;
1092 break;
1093 #ifdef EASY_OPENINGS
1094 case '~' :
1095 GameList[GameCnt].flags |= difficult;
1096 break;
1097 #endif
1102 void
1103 Undo (void)
1106 * Undo the most recent half-move.
1110 short f, t;
1111 f = GameList[GameCnt].gmove >> 8;
1112 t = GameList[GameCnt].gmove & 0x7F;
1113 if ( f > NO_SQUARES )
1114 { /* the move was a drop */
1115 Captured[color[t]][board[t]]++;
1116 board[t] = no_piece;
1117 color[t] = neutral;
1118 Mvboard[t]--;
1120 else
1122 if ( GameList[GameCnt].flags & promote )
1123 board[f] = unpromoted[board[t]];
1124 else
1125 board[f] = board[t];
1126 color[f] = color[t];
1127 board[t] = GameList[GameCnt].piece;
1128 color[t] = GameList[GameCnt].color;
1129 if ( board[t] != no_piece )
1130 Captured[color[f]][unpromoted[board[t]]]--;
1131 if (color[t] != neutral)
1132 Mvboard[t]--;
1133 Mvboard[f]--;
1135 InitializeStats ();
1137 if (TCflag && (TCmoves>1))
1138 ++TimeControl.moves[color[f]];
1139 hashkey = GameList[GameCnt].hashkey;
1140 hashbd = GameList[GameCnt].hashbd;
1141 GameCnt--;
1142 computer = computer ^ 1;
1143 opponent = opponent ^ 1;
1144 flag.mate = false;
1145 Sdepth = 0;
1146 player = player ^ 1;
1147 ShowSidetoMove ();
1148 UpdateDisplay (0, 0, 1, 0);
1149 if (flag.regularstart)
1150 Book = false;
1155 #if !defined XSHOGI
1158 void
1159 FlagString (unsigned short flags, char *s)
1161 short l,piece;
1162 *s = '\0';
1163 if ( flags & promote )
1164 strcat (s, " promote");
1165 if ( flags & dropmask )
1166 strcat (s, " drop:");
1167 if ( piece = (flags & pmask) ) {
1168 l=strlen(s);
1169 if(is_promoted[piece])
1170 s[l++] = '+';
1171 s[l++] = pxx[piece];
1172 s[l]='\0';
1174 if ( flags & capture )
1175 strcat (s, " capture");
1176 if ( flags & exact )
1177 strcat (s, " exact");
1178 if ( flags & tesuji )
1179 strcat (s, " tesuji");
1180 if ( flags & check )
1181 strcat (s, " check");
1182 if ( flags & draw )
1183 strcat (s, " draw");
1184 if ( flags & stupid )
1185 strcat (s, " stupid");
1186 if ( flags & questionable )
1187 strcat (s, " questionable");
1188 if ( flags & kingattack )
1189 strcat (s, " kingattack");
1190 if ( flags & book )
1191 strcat (s, " book");
1196 void
1197 TestSpeed (void (*f) (short int side, short int ply, short int in_check, short int blockable),
1198 unsigned j)
1200 #ifdef test
1201 unsigned jj;
1202 #endif
1203 unsigned i;
1204 long cnt, rate, t1, t2;
1205 #ifdef HASGETTIMEOFDAY
1206 struct timeval tv;
1207 #endif
1209 #ifdef HASGETTIMEOFDAY
1210 gettimeofday(&tv,NULL);
1211 t1 = (tv.tv_sec*100+(tv.tv_usec/10000));
1212 #elif defined THINK_C || defined MSDOS
1213 t1 = clocktime();
1214 #else
1215 t1 = time (0);
1216 #endif
1217 #ifdef DEBUG_EVAL
1218 debug_moves = true;
1219 #endif
1220 for (i = 0; i < j; i++)
1222 f (opponent, 2, -1, true);
1223 #ifdef test
1224 for(jj=TrPnt[2];i<TrPnt[3];jj++)if(!pick(jj,TrPnt[3]-1))break;
1225 #endif
1227 #ifdef DEBUG_EVAL
1228 debug_moves = false;
1229 #endif
1230 #ifdef HASGETTIMEOFDAY
1231 gettimeofday(&tv,NULL);
1232 t2 = (tv.tv_sec*100+(tv.tv_usec/10000));
1233 #elif defined THINK_C || defined MSDOS
1234 t2 = clocktime();
1235 #else
1236 t2 = time (0);
1237 #endif
1238 cnt = j * (TrPnt[3] - TrPnt[2]);
1239 if (t2 - t1)
1240 et = (t2 - t1);
1241 else
1242 et = 1;
1243 rate = (((et) ? ((cnt*100) / et) : 0));
1244 #ifdef DYNAMIC_ZNODES
1245 if ( rate > 0 )
1246 znodes = rate;
1247 #endif
1248 /*printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);*/
1249 #ifdef NONDSP
1250 printz (CP[91], cnt, rate);
1251 #ifdef DEBUG9
1252 for (j = TrPnt[2]; j < TrPnt[3]; j++)
1254 struct leaf far *node = &Tree[j];
1255 algbr (node->f, node->t, node->flags);
1256 #ifdef DEBUG_EVAL
1257 if ( debug_eval )
1259 #if defined FIELDBONUS || defined DROPBONUS
1260 if ( node->score <= DONTUSE )
1261 fprintf (debug_eval_file, "%s %s %s %s DONTUSE",
1262 mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
1263 else
1264 fprintf (debug_eval_file, "%s %s %s %s score %d INC %d",
1265 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->score,node->INCscore);
1266 #else
1267 if ( node->score <= DONTUSE )
1268 fprintf (debug_eval_file, "%s %s %s %s DONTUSE",
1269 mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
1270 else
1271 fprintf (debug_eval_file, "%s %s %s %s score %d",
1272 mvstr[0], mvstr[1], mvstr[2], mvstr[3], node->score);
1273 #endif
1274 if ( node->flags )
1275 { char s[80];
1276 FlagString(node->flags, s);
1277 fprintf(debug_eval_file,"%s",s);
1279 #ifdef HISTORY
1280 { short mv;
1281 unsigned short hi0, hi1;
1282 mv = (node->f << 8) | node->t;
1283 if ( node->flags & promote ) mv |= 0x80;
1284 hi0 = hindex(0,mv);
1285 hi1 = hindex(1,mv);
1286 fprintf (debug_eval_file, " mv=%x hi0=%x hi1=%x",mv, hi0, hi1);
1288 #endif
1289 fprintf (debug_eval_file, "\n");
1290 } else
1291 #endif
1292 #if defined FIELDBONUS || defined DROPBONUS
1293 if ( node->score <= DONTUSE )
1294 printf ("%s %s %s %s DONTUSE %x\n",
1295 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->flags);
1296 else
1297 printf ("%s %s %s %s score %d INC %d %x\n",
1298 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->score,node->INCscore,node->flags);
1299 #else
1300 if ( node->score <= DONTUSE )
1301 printf ("%s %s %s %s DONTUSE %x\n",
1302 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->flags);
1303 else
1304 printf ("%s %s %s %s score %d %x\n",
1305 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->score,node->flags);
1306 #endif
1308 #endif
1309 #else
1310 ShowNodeCnt (cnt);
1311 #endif
1314 void
1315 TestPSpeed (short int (*f) (short int side), unsigned j)
1317 short i;
1318 long cnt, rate, t1, t2;
1319 #ifdef HASGETTIMEOFDAY
1320 struct timeval tv;
1321 #endif
1323 #ifdef HASGETTIMEOFDAY
1324 gettimeofday(&tv,NULL);
1325 t1 = (tv.tv_sec*100+(tv.tv_usec/10000));
1326 #elif defined THINK_C || defined MSDOS
1327 t1 = clocktime();
1328 #else
1329 t1 = time (0);
1330 #endif
1331 for (i = 0; i < j; i++)
1333 (void) f (opponent);
1335 #ifdef HASGETTIMEOFDAY
1336 gettimeofday(&tv,NULL);
1337 t2 = (tv.tv_sec*100+(tv.tv_usec/10000));
1338 #elif defined THINK_C || defined MSDOS
1339 t2 = clocktime();
1340 #else
1341 t2 = time (0);
1342 #endif
1343 cnt = j;
1344 if (t2 - t1)
1345 et = (t2 - t1);
1346 else
1347 et = 1;
1348 rate = (et) ? ((cnt*100) / et) : 0;
1349 /*printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);*/
1350 #ifdef NONDSP
1351 printz (CP[91], cnt, rate);
1352 #else
1353 ShowNodeCnt (cnt);
1354 #endif
1358 #endif /* XSHOGI */
1361 void
1362 SetOppTime (char *s)
1364 char *time;
1365 char buffer[20];
1366 register tmp = 0;
1367 int m, t,sec;
1368 sec = 0;
1369 time = &s[strlen (CP[197])];
1370 t = (int)strtol (time, &time, 10);
1371 if(*time == ':'){time++; sec=(int)strtol(time, &time,10);}
1372 m = (int)strtol (time, &time, 10);
1373 if (t)
1374 TimeControl.clock[opponent] = t;
1375 if (m)
1376 TimeControl.moves[opponent] = m;
1377 #if defined XSHOGI
1378 printz (CP[222], m, t);
1379 #endif
1384 void
1385 SetMachineTime (char *s)
1387 char *time;
1388 long tmp = 0;
1389 int m, t,sec;
1390 time = &s[strlen (CP[197])];
1391 sec = 0;
1392 t = (int)strtol (time, &time, 10);
1393 if(*time == ':'){time++; sec=(int)strtol(time, &time,10);}
1394 m = (int)strtol (time, &time, 10);
1395 if (t)
1396 TimeControl.clock[computer] = t;
1397 if (m)
1398 TimeControl.moves[computer] = m;
1399 #if defined XSHOGI
1400 printz (CP[222], m, t);
1401 #endif
1405 #if defined DEBUG || defined DEBUG_EVAL
1406 void debug_position (FILE *D)
1408 short r, c, side, piece, l;
1409 fprintf (D, "\n current board is\n\n");
1410 for (piece = pawn; piece <= king; piece++)
1411 if (c = Captured[white][piece])
1412 fprintf(D, "%i%c ",c,pxx[piece]);
1413 fprintf (D, "\n");
1414 for (c = 0; c < NO_COLS; c++)
1415 fprintf (D, " %d", PawnCnt[white][c]);
1416 fprintf (D, "\n\n");
1417 for (r = NO_ROWS-1; r >= 0; r--)
1418 { char pc;
1419 for (c = 0; c <= NO_COLS-1; c++)
1421 l = locn (r, c);
1422 pc = (is_promoted[board[l]] ? '+' : ' ');
1423 if (color[l] == neutral)
1424 fprintf (D, " -");
1425 else if (color[l] == black)
1426 fprintf (D, "%c%c", pc, qxx[board[l]]);
1427 else
1428 fprintf (D, "%c%c", pc, pxx[board[l]]);
1430 fprintf (D, "\n");
1432 fprintf (D, "\n");
1433 for (c = 0; c < NO_COLS; c++)
1434 fprintf (D, " %d", PawnCnt[black][c]);
1435 fprintf (D, "\n");
1436 for (piece = pawn; piece <= king; piece++)
1437 if (c = Captured[black][piece])
1438 fprintf(D, "%i%c ",c,pxx[piece]);
1439 fprintf (D, "\n");
1441 #endif
1445 void
1446 InputCommand (char *command)
1449 * Process the users command. If easy mode is OFF (the computer is thinking
1450 * on opponents time) and the program is out of book, then make the 'hint'
1451 * move on the board and call SelectMove() to find a response. The user
1452 * terminates the search by entering ^C (quit siqnal) before entering a
1453 * command. If the opponent does not make the hint move, then set Sdepth to
1454 * zero.
1458 int eof = 0;
1459 short have_shown_prompt = false;
1460 short ok, done;
1461 unsigned short mv;
1462 char s[80], sx[80];
1464 ok = flag.quit = done = false;
1465 player = opponent;
1466 #if ttblsz
1467 if(TTadd > ttbllimit)ZeroTTable();
1468 #endif
1469 if (hint > 0 && !flag.easy && !flag.force )
1471 /* A hint move for the player is available.
1472 Compute a move for the oppnonent in background mode assuming
1473 that the hint move will be selected by the player. */
1474 ft = time0; /* Save reference time for the player. */
1475 fflush (stdout);
1476 algbr ((short) hint >> 8, (short) hint & 0xff, false);
1477 strcpy (s, mvstr[0]);
1478 #ifdef DEBUG12
1479 if (1)
1481 FILE *D;
1482 int r, c, l;
1483 extern unsigned short int PrVar[];
1484 extern struct leaf far *root;
1485 D = fopen ("/tmp/DEBUGA", "a+");
1486 fprintf (D, "score = %d\n", root->score);
1487 fprintf (D, "inout move is %s\n", s);
1488 for (r = 1; PrVar[r]; r++)
1490 algbr (PrVar[r] >> 8, PrVar[r] & 0xff, (short) 0);
1491 fprintf (D, " %s", mvstr[0]);
1493 fclose (D);
1495 #endif
1496 #if !defined NOPOST
1497 if (flag.post) GiveHint ();
1498 #endif
1499 /* do the hint move */
1500 if (VerifyMove (s, VERIFY_AND_TRY_MODE, &mv))
1503 Sdepth = 0;
1504 #ifdef QUIETBACKGROUND
1505 #ifdef NONDSP
1506 PromptForMove ();
1507 #else
1508 ShowSidetoMove ();
1509 ShowPrompt ();
1510 #endif
1511 have_shown_prompt = true;
1512 #endif /* QUIETBACKGROUND */
1513 /* Start computing a move until the search is interrupted. */
1514 #ifdef INTERRUPT_TEST
1515 itime0 = 0;
1516 #endif
1517 /* would love to put null move in here */
1518 /* after we make the hint move make a 2 ply search with both plys our moves */
1519 /* think on opponents time */
1520 SelectMove (computer, BACKGROUND_MODE);
1521 #ifdef INTERRUPT_TEST
1522 ElapsedTime(COMPUTE_INTERRUPT_MODE);
1523 if ( itime0 == 0 )
1524 printf("searching not terminated by interrupt!\n");
1525 else
1526 printf("elapsed time from interrupt to terminating search: %ld\n",it);
1527 #endif
1528 /* undo the hint and carry on */
1529 VerifyMove (s, UNMAKE_MODE, &mv);
1530 Sdepth = 0;
1532 time0 = ft; /* Restore reference time for the player. */
1534 while (!(ok || flag.quit || done))
1536 player = opponent;
1537 #ifdef QUIETBACKGROUND
1538 if (!have_shown_prompt)
1540 #endif /* QUIETBACKGROUND */
1541 #ifdef NONDSP
1542 PromptForMove ();
1543 #else
1544 ShowSidetoMove ();
1545 ShowPrompt ();
1546 #endif
1547 #ifdef QUIETBACKGROUND
1549 have_shown_prompt = false;
1550 #endif /* QUIETBACKGROUND */
1551 if ( command == NULL )
1553 #ifdef NONDSP
1554 s[0] = sx[0] = '\0';
1555 while (!sx[0])
1556 (void) gets (sx);
1557 #else
1558 fflush (stdout);
1559 #if defined MSDOS || defined THINK_C
1560 s[0] = '\0';
1561 eof = ( gets (sx) == NULL );
1562 #else
1563 eof = ( getstr (sx) == ERR );
1564 #endif
1565 #endif
1567 else
1569 strcpy (sx, command);
1570 done = true;
1572 sscanf (sx, "%s", s);
1573 if (eof)
1574 ExitChess ();
1575 if (s[0] == '\0')
1576 continue;
1577 if (strcmp (s, CP[131]) == 0) /*bd*/
1579 #if defined XSHOGI
1580 xshogi = 0;
1581 #endif
1582 ClrScreen ();
1583 UpdateDisplay (0, 0, 1, 0);
1584 #if defined XSHOGI
1585 xshogi = 1;
1586 #endif
1588 else if (strcmp (s, "post") == 0)
1589 flag.post = !flag.post;
1590 else if (strcmp (s, CP[129]) == 0) /* noop */ ; /*alg*/
1591 else if ((strcmp (s, CP[180]) == 0) || (strcmp (s, CP[216]) == 0)) /* quit exit*/
1592 flag.quit = true;
1593 #if !defined NOPOST
1594 else if (strcmp (s, CP[178]) == 0) /*post*/
1596 flag.post = !flag.post;
1598 #endif
1599 else if ((strcmp (s, CP[191]) == 0) || (strcmp (s, CP[154]) == 0)) /*set edit*/
1600 EditBoard ();
1601 #ifdef NONDSP
1602 else if (strcmp (s, CP[190]) == 0) /*setup*/
1603 SetupBoard ();
1604 #endif
1605 else if (strcmp (s, CP[156]) == 0) /*first*/
1607 ok = true;
1609 else if (strcmp (s, CP[162]) == 0) /*go*/
1611 ok = true;
1612 flag.force = false;
1613 if (computer == black)
1615 computer = white;
1616 opponent = black;
1618 else
1620 computer = black;
1621 opponent = white;
1624 else if (strcmp (s, CP[166]) == 0) /*help*/
1625 help ();
1626 else if (strcmp (s, CP[221]) == 0) /*material*/
1627 flag.material = !flag.material;
1628 else if (strcmp (s, CP[157]) == 0) /*force*/
1629 {flag.force = !flag.force; flag.bothsides = false;}
1630 else if (strcmp (s, CP[134]) == 0) /*book*/
1631 Book = Book ? 0 : BOOKFAIL;
1632 else if (strcmp (s, CP[172]) == 0) /*new*/
1634 NewGame ();
1635 UpdateDisplay (0, 0, 1, 0);
1637 else if (strcmp (s, CP[171]) == 0) /*list*/
1638 ListGame ();
1639 else if (strcmp (s, CP[169]) == 0 || strcmp (s, CP[217]) == 0) /*level clock*/
1640 SelectLevel (sx);
1641 else if (strcmp (s, CP[165]) == 0) /*hash*/
1642 flag.hash = !flag.hash;
1643 else if (strcmp (s, CP[227]) == 0) /*gamein*/
1644 flag.gamein = !flag.gamein;
1645 else if (strcmp (s, CP[226]) == 0) /*beep*/
1646 flag.beep = !flag.beep;
1647 else if (strcmp (s, CP[197]) == 0) /*time*/
1648 { SetMachineTime (sx); }
1649 else if (strcmp (s, CP[228]) == 0) /*otime*/
1650 { SetOppTime (sx); }
1651 else if (strcmp (s, CP[33]) == 0) /*Awindow*/
1652 ChangeAlphaWindow ();
1653 else if (strcmp (s, CP[39]) == 0) /*Bwindow*/
1654 ChangeBetaWindow ();
1655 else if (strcmp (s, CP[183]) == 0) /*rcptr*/
1656 flag.rcptr = !flag.rcptr;
1657 else if (strcmp (s, CP[168]) == 0) /*hint*/
1658 GiveHint ();
1659 else if (strcmp (s, CP[135]) == 0) /*both*/
1661 flag.bothsides = !flag.bothsides;
1662 flag.force = false;
1663 Sdepth = 0;
1664 ElapsedTime (COMPUTE_AND_INIT_MODE);
1665 SelectMove (opponent, FOREGROUND_MODE);
1666 ok = true;
1668 else if (strcmp (s, CP[185]) == 0) /*reverse*/
1670 flag.reverse = !flag.reverse;
1671 ClrScreen ();
1672 UpdateDisplay (0, 0, 1, 0);
1674 else if (strcmp (s, CP[195]) == 0) /*switch*/
1676 computer = computer ^ 1;
1677 opponent = opponent ^ 1;
1678 xwndw = (computer == black) ? WXWNDW : BXWNDW;
1679 flag.force = false;
1680 Sdepth = 0;
1681 ok = true;
1683 else if (strcmp (s, CP[203]) == 0) /*black*/
1685 computer = white;
1686 opponent = black;
1687 xwndw = WXWNDW;
1688 flag.force = false;
1689 Sdepth = 0;
1692 * ok = true; don't automatically start with black command
1695 else if (strcmp (s, CP[133]) == 0) /*white*/
1697 computer = black;
1698 opponent = white;
1699 xwndw = BXWNDW;
1700 flag.force = false;
1701 Sdepth = 0;
1704 * ok = true; don't automatically start with white command
1707 else if (strcmp (s, CP[201]) == 0 && GameCnt > 0) /*undo*/
1709 Undo ();
1711 else if (strcmp (s, CP[184]) == 0 && GameCnt > 1) /*remove*/
1713 Undo ();
1714 Undo ();
1716 #if !defined XSHOGI
1717 else if (strcmp (s, CP[207]) == 0) /*xget*/
1718 GetXGame ();
1719 else if (strcmp (s, "xsave") == 0) /*xsave*/
1720 SaveXGame ();
1721 else if (strcmp (s, "bsave") == 0) /*bsave*/
1722 BookSave ();
1723 #endif
1724 #ifdef EASY_OPENINGS
1725 else if (strcmp (s, "?") == 0 || strcmp (s, "!") == 0 || strcmp (s, "~") == 0)
1726 #else
1727 else if (strcmp (s, "?") == 0 || strcmp (s, "!") == 0)
1728 #endif
1729 FlagMove (*s);
1730 else if (strcmp (s, CP[160]) == 0) /*get*/
1731 GetGame ();
1732 else if (strcmp (s, CP[189]) == 0) /*save*/
1733 SaveGame ();
1734 else if (strcmp (s, CP[151]) == 0) /*depth*/
1735 ChangeSearchDepth ();
1736 #ifdef DEBUG
1737 else if (strcmp (s, CP[147]) == 0) /*debuglevel*/
1738 ChangeDbLev ();
1739 #endif /* DEBUG */
1740 else if (strcmp (s, CP[164]) == 0) /*hashdepth*/
1741 ChangeHashDepth ();
1742 else if (strcmp (s, CP[182]) == 0) /*random*/
1743 dither = DITHER;
1744 else if (strcmp (s, CP[229]) == 0) /*hard*/
1745 flag.easy = false;
1746 else if (strcmp (s, CP[152]) == 0) /*easy*/
1747 flag.easy = !flag.easy;
1748 else if (strcmp (s, CP[230]) == 0) /*tsume*/
1749 flag.tsume = !flag.tsume;
1750 else if (strcmp (s, CP[143]) == 0) /*contempt*/
1751 SetContempt ();
1752 else if (strcmp (s, CP[209]) == 0) /*xwndw*/
1753 ChangeXwindow ();
1754 else if (strcmp (s, CP[186]) == 0) /*rv*/
1756 flag.rv = !flag.rv;
1757 UpdateDisplay (0, 0, 1, 0);
1759 else if (strcmp (s, CP[145]) == 0) /*coords*/
1761 flag.coords = !flag.coords;
1762 UpdateDisplay (0, 0, 1, 0);
1764 else if (strcmp (s, CP[193]) == 0) /*stars*/
1766 flag.stars = !flag.stars;
1767 UpdateDisplay (0, 0, 1, 0);
1769 #if !defined XSHOGI
1770 else if (strcmp (s, CP[5]) == 0) /*moves*/
1772 #ifdef DEBUG_EVAL
1773 debug_eval = ((debug_eval_file = fopen(EVALFILE,"w")) != NULL);
1774 #endif
1775 #if MAXDEPTH > 3
1776 if ( GameCnt > 0 ) {
1777 extern unsigned short int PrVar[MAXDEPTH];
1778 SwagHt = (GameList[GameCnt].gmove == PrVar[1]) ? PrVar[2] : 0;
1779 } else
1780 #endif
1781 SwagHt = 0;
1782 ShowMessage (CP[108]); /*test movelist*/
1783 TestSpeed (MoveList, 1);
1784 ShowMessage (CP[107]); /*test capturelist*/
1785 TestSpeed (CaptureList, 1);
1786 ShowMessage (CP[85]); /*test score position*/
1787 ExaminePosition(opponent);
1788 TestPSpeed (ScorePosition, 1);
1789 #ifdef DEBUG_EVAL
1790 if ( debug_eval ) fclose(debug_eval_file);
1791 debug_eval = false;
1792 #endif
1794 else if (strcmp (s, CP[196]) == 0) /*test*/
1796 #ifdef SLOW_CPU
1797 ShowMessage (CP[108]);/*test movelist*/
1798 TestSpeed (MoveList, 2000);
1799 ShowMessage (CP[107]);/*test capturelist*/
1800 TestSpeed (CaptureList, 3000);
1801 ShowMessage (CP[85]);/*test score position*/
1802 ExaminePosition(opponent);
1803 TestPSpeed (ScorePosition, 1500);
1804 #else
1805 ShowMessage (CP[108]);/*test movelist*/
1806 TestSpeed (MoveList, 20000);
1807 ShowMessage (CP[107]);/*test capturelist*/
1808 TestSpeed (CaptureList, 30000);
1809 ShowMessage (CP[85]);/*test score position*/
1810 ExaminePosition(opponent);
1811 TestPSpeed (ScorePosition, 15000);
1812 #endif
1814 #ifdef DEBUG_EVAL
1815 else if (strcmp (s, "eval") == 0) /*eval*/
1817 debug_eval = true;
1818 if ( debug_eval_file = fopen(EVALFILE,"w") ) {
1819 InitializeStats();
1820 ExaminePosition(opponent);
1821 fprintf (debug_eval_file, "\nscoring for %s to move...\n\n",
1822 ColorStr[player]);
1823 ScorePosition (player);
1824 fclose (debug_eval_file);
1826 debug_eval = false;
1828 else if (strcmp (s, "debug_eval") == 0) /*debug_eval*/
1830 if ( debug_eval )
1832 fclose (debug_eval_file);
1833 debug_eval = false;
1835 else
1837 debug_eval_file = fopen(EVALFILE,"w");
1838 debug_eval = (debug_eval_file != NULL);
1841 else if (strcmp (s, "pattern") == 0) /*pattern*/
1843 debug_eval = true;
1844 if ( debug_eval_file = fopen(EVALFILE,"w") ) {
1845 short side;
1846 for (side=black; side<=white; side++) {
1847 short s = ScorePatternDistance (side);
1848 fprintf (debug_eval_file, "\npattern distance score for %s is %d\n\n",
1849 ColorStr[side], s);
1851 fclose (debug_eval_file);
1853 debug_eval = false;
1855 #endif /* DEBUG_EVAL */
1856 else
1857 if (strcmp (s, CP[179]) == 0) /*p*/
1858 ShowPostnValues ();
1859 else if (strcmp (s, CP[148]) == 0) /*debug*/
1860 DoDebug ();
1861 #endif /* XSHOGI */
1862 else
1864 if ( flag.mate )
1865 ok = true;
1866 else if ( ok = VerifyMove (s, VERIFY_AND_MAKE_MODE, &mv) )
1868 /* check for repetition */
1869 short int rpt = repetition();
1870 if ( rpt >= 3 )
1871 { DRAW = CP[101];
1872 ShowMessage(DRAW);
1873 GameList[GameCnt].flags |= draw;
1874 flag.mate = true;
1877 Sdepth = 0;
1881 ElapsedTime (COMPUTE_AND_INIT_MODE);
1883 if (flag.force)
1885 computer = opponent;
1886 opponent = computer ^ 1;
1888 #if defined XSHOGI
1889 /* add remaining time in milliseconds for xshogi */
1890 printz ("%d. %s %ld\n", ++mycnt2, s, TimeControl.clock[player]*10);
1891 #ifdef notdef /* optional pass best line to frontend with move */
1892 #if !defined NOPOST
1893 if (flag.post && !flag.mate)
1895 register int i;
1897 printz (" %6d ", MSCORE);
1898 for (i = 1; MV[i] > 0; i++)
1900 algbr ((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
1901 printz ("%5s ", mvstr[0]);
1904 #endif
1905 printz ("\n");
1906 #endif
1907 #endif /* XSHOGI */
1908 signal (SIGINT, TerminateSearch);
1909 #if !defined MSDOS && !defined THINK_C && !defined BORLAND_CPP
1910 signal (SIGQUIT, TerminateSearch);
1911 #endif /* MSDOS */
1916 #if defined NOFIONREAD
1917 #ifdef FIONREAD
1918 #undef FIONREAD
1919 #endif
1920 #endif
1925 #ifdef HASGETTIMEOFDAY
1926 void
1927 ElapsedTime (ElapsedTime_mode iop)
1931 * Determine the time that has passed since the search was started. If the
1932 * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
1933 * to true which will terminate the search.
1934 * iop = COMPUTE_MODE calculate et, bump ETnodes
1935 * iop = COMPUTE_AND_INIT_MODE calculate et, set timeout if time exceeded,
1936 * set reference time
1940 struct timeval tv;
1941 long current_time;
1942 #if !defined MSDOS
1943 int nchar;
1944 extern int errno;
1945 int i;
1946 #ifdef FIONREAD
1947 if (i = ioctl ((int) 0, FIONREAD, &nchar))
1949 perror ("FIONREAD");
1950 fprintf (stderr,
1951 "You probably have a non-ANSI <ioctl.h>; see README. %d %d %x\n",
1952 i, errno, FIONREAD);
1953 exit (1);
1956 if (nchar)
1958 if (!flag.timeout)
1959 flag.back = true;
1960 flag.bothsides = false;
1962 #endif /*FIONREAD*/
1963 #else
1964 if (kbhit ())
1966 if (!flag.timeout)
1967 flag.back = true;
1968 flag.bothsides = false;
1970 #endif /* MSDOS */
1971 gettimeofday(&tv,NULL);
1972 current_time = tv.tv_sec*100 + (tv.tv_usec/10000);
1973 #ifdef INTERRUPT_TEST
1974 if ( iop == INIT_INTERRUPT_MODE )
1976 itime0 = current_time;
1978 else if ( iop == COMPUTE_INTERRUPT_MODE )
1980 it = current_time - itime0;
1982 else
1983 #endif
1985 et = current_time - time0;
1986 ETnodes = NodeCnt + znodes;
1987 if (et < 0)
1989 #ifdef INTERRUPT_TEST
1990 printf("elapsed time %ld not positive\n", et);
1991 #endif
1992 et = 0;
1994 if (iop == COMPUTE_AND_INIT_MODE)
1996 if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
1997 flag.timeout = true;
1998 time0 = current_time;
2000 #if !defined NONDSP
2001 #ifdef QUIETBACKGROUND
2002 if (!background)
2003 #endif /* QUIETBACKGROUND */
2004 UpdateClocks ();
2005 #endif
2009 #else
2011 void
2012 ElapsedTime (ElapsedTime_mode iop)
2016 * Determine the time that has passed since the search was started. If the
2017 * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
2018 * to true which will terminate the search. iop = 0 calculate et bump ETnodes
2019 * iop = 1 calculate et set timeout if time exceeded, calculate et
2023 long current_time;
2024 #if !defined MSDOS
2025 int nchar;
2026 extern int errno;
2027 int i;
2028 #ifdef FIONREAD
2029 if (i = ioctl ((int) 0, FIONREAD, &nchar))
2031 perror ("FIONREAD");
2032 fprintf (stderr,
2033 "You probably have a non-ANSI <ioctl.h>; see README. %d %d %x\n",
2034 i, errno, FIONREAD);
2035 exit (1);
2038 if (nchar)
2040 if (!flag.timeout)
2041 flag.back = true;
2042 flag.bothsides = false;
2044 #endif /*FIONREAD*/
2045 #else
2046 if (kbhit ())
2048 if (!flag.timeout)
2049 flag.back = true;
2050 flag.bothsides = false;
2052 #endif /* MSDOS */
2053 #if defined THINK_C || defined MSDOS
2054 et = ((current_time = clocktime()) - time0);
2055 #else
2056 et = ((current_time = time ((long *) 0)) - time0) * 100;
2057 #endif
2058 #ifdef INTERRUPT_TEST
2059 if ( iop == INIT_INTERRUPT_MODE )
2061 itime0 = current_time;
2063 else if ( iop == COMPUTE_INTERRUPT_MODE )
2065 it = current_time - itime0;
2067 else
2068 #endif
2070 ETnodes = NodeCnt + znodes;
2071 if (et < 0)
2073 #ifdef INTERRUPT_TEST
2074 printf("elapsed time %ld not positive\n", et);
2075 #endif
2076 et = 0;
2078 if (iop == COMPUTE_AND_INIT_MODE)
2080 if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
2081 flag.timeout = true;
2082 time0 = current_time;
2084 #if !defined NONDSP
2085 #ifdef QUIETBACKGROUND
2086 if (!background)
2087 #endif /* QUIETBACKGROUND */
2088 UpdateClocks ();
2089 #endif
2092 #endif
2093 void
2094 SetTimeControl (void)
2096 if (TCflag)
2098 TimeControl.moves[black] = TimeControl.moves[white] = TCmoves;
2099 TimeControl.clock[black] += 6000L * TCminutes + TCseconds * 100;
2100 TimeControl.clock[white] += 6000L * TCminutes + TCseconds * 100;
2102 else
2104 TimeControl.moves[black] = TimeControl.moves[white] = 0;
2105 TimeControl.clock[black] = TimeControl.clock[white] = 0;
2107 flag.onemove = (TCmoves == 1);
2108 et = 0;
2109 ElapsedTime (COMPUTE_AND_INIT_MODE);
2112 #if defined XSHOGI
2113 void
2114 TerminateChess (int sig)
2116 ExitChess ();
2119 #endif