2 * dspcom.c - C source for GNU SHOGI
4 * Copyright (c) 1993, 1994, 1995 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)
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.
30 #if defined HASGETTIMEOFDAY
35 int InBackground = false;
50 #include <sys/param.h>
51 #include <sys/types.h>
53 #include <sys/ioctl.h>
56 #if defined DEBUG || defined DEBUG_EVAL
57 short debug_eval = false;
58 FILE *debug_eval_file = NULL;
59 short debug_moves = false;
63 #if defined DEBUG || defined BOOKTEST || defined DEBUG_EVAL
66 movealgbr (short int m, char *s)
69 short piece = 0, flag = 0;
78 { piece = f - NO_SQUARES;
79 if ( piece > NO_PIECES ) piece -= NO_PIECES;
80 flag = (dropmask | piece);
87 if ( flag & dropmask )
91 *s = cxx[column (t)]; s++;
92 *s = rxx[row (t)]; s++;
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 )
116 algbr (short int f, short int t, short int flag)
120 * Generate move strings in different formats.
126 if ( f > NO_SQUARES )
128 piece = f - NO_SQUARES;
129 if ( f > (NO_SQUARES+NO_PIECES) )
131 flag = (dropmask | piece);
133 if ( (t & 0x80) != 0 )
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);
143 mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
146 if ( (flag & dropmask) != 0 )
147 { short piece = flag & pmask;
148 mvstr[0][0] = pxx[piece];
150 mvstr[0][2] = cxx[column (t)];
151 mvstr[0][3] = rxx[row (t)];
153 strcpy (mvstr[1], mvstr[0]);
154 strcpy (mvstr[2], mvstr[0]);
155 strcpy (mvstr[3], mvstr[0]);
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];
178 strcat(mvstr[0], "+");
179 strcat(mvstr[1], "+");
180 strcat(mvstr[2], "+");
181 strcat(mvstr[3], "+");
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++)
207 case '?' : local_flags |= badmove; s[i]='\0'; break;
208 case '!' : local_flags |= goodmove; s[i]='\0'; break;
210 case '~' : local_flags |= difficult; s[i]='\0'; break;
215 if (iop == UNMAKE_MODE)
217 UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
221 if (iop == VERIFY_AND_MAKE_MODE)
222 generate_move_flags = true;
223 MoveList (opponent, 2, -1, true);
224 generate_move_flags = false;
226 while (pnt < TrPnt[3])
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)
237 if (cnt == 1 && xnode.score > DONTUSE)
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);
245 /* Illegal move in check */
247 printz ("Illegal move (in check) %s",mvstr[0]);
249 printz (CP[77], mvstr[0]);
253 /* Illegal move in check */
254 sprintf (buffer, CP[77], s);
255 ShowMessage (buffer);
261 if (iop == VERIFY_AND_TRY_MODE)
263 UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
264 GameList[GameCnt].depth = GameList[GameCnt].score = 0;
265 GameList[GameCnt].nodes = 0;
266 ElapsedTime (COMPUTE_AND_INIT_MODE);
267 GameList[GameCnt].time = (short) (et+50)/100;
268 GameList[GameCnt].flags |= local_flags;
271 TimeControl.clock[opponent] -= et;
272 timeopp[oppptr] = et;
273 --TimeControl.moves[opponent];
275 *mv = (xnode.f << 8) | xnode.t;
276 algbr (xnode.f, xnode.t, false);
277 /* in force mode, check for mate conditions */
280 if ( IsCheckmate(opponent ^ 1,-1,-1) )
281 { char buf[20],buf2[20];
282 sprintf(buf,"%s mates!\n",ColorStr[opponent]);
293 printz ("Illegal move (no match) %s\n", s);
302 extern unsigned short int PrVar[];
303 D = fopen ("/tmp/DEBUG", "a+");
305 fprintf (D, "resp = %d\n", ResponseTime);
306 fprintf (D, "iop = %d\n", iop);
307 fprintf (D, "matches = %d\n", cnt);
308 algbr (hint >> 8, hint & 0xff, (short) 0);
309 fprintf (D, "hint %s\n", mvstr[0]);
310 fprintf (D, "inout move is %s\n", s);
311 for (r = 1; PrVar[r]; r++)
313 algbr (PrVar[r] >> 8, PrVar[r] & 0xff, (short) 0);
314 fprintf (D, " %s", mvstr[0]);
317 fprintf (D, "legal move are \n");
318 while (pnt < TrPnt[3])
321 algbr (node->f, node->t, (short) node->flags);
322 fprintf (D, "%s %s %s %s\n", mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
331 sprintf(buffer,CP[76],s);
332 ShowMessage (buffer);
334 #if !defined BAREBONES
336 sprintf(buffer,CP[32],s);
346 parser (char *f, int side, short *fpiece)
352 for ( i = 1, *fpiece = no_piece; i<NO_PIECES; i++ )
353 if ( f[0] == pxx[i] || f[0] == qxx[i] )
355 *fpiece = (p ? promoted[i] : unpromoted[i]);
358 if ( f[1] == '*' || f[1] == '\'' )
362 return ((NO_SQUARES + *fpiece) << 8) | locn (r2, c2);
370 p = (f[5] == '+') ? 0x80 : 0;
371 return (locn (r1, c1) << 8) | locn (r2, c2) | p;
379 while (*InPtr != ' ')
381 while (*InPtr == ' ')
388 while (*InPtr == ' ')
402 strcpy (fname, savefile);
406 ShowMessage (CP[63]);
410 if (fname[0] == '\0')
411 strcpy (fname, CP[137]);
412 if ((fd = fopen (fname, "r")) != NULL)
415 fgets (fname, 256, fd);
416 computer = opponent = black;
426 Game50 = atoi (InPtr);
428 flag.force = (*InPtr == 'f');
429 fgets (fname, 256, fd); /* empty */
430 fgets (fname, 256, fd);
433 TCflag = atoi (InPtr);
437 OperatorTime = atoi (InPtr);
438 fgets (fname, 256, fd);
441 TimeControl.clock[black] = atol (InPtr);
444 TimeControl.moves[black] = atoi (InPtr);
445 fgets (fname, 256, fd);
448 TimeControl.clock[white] = atol (InPtr);
451 TimeControl.moves[white] = atoi (InPtr);
452 fgets (fname, 256, fd); /* empty */
453 for (i = NO_ROWS-1; i > -1; i--)
455 fgets (fname, 256, fd);
458 for (j = 0; j < NO_COLS; j++)
460 sq = i * NO_COLS + j;
465 board[sq] = no_piece;
470 for (c = 0; c < NO_PIECES; c++)
475 board[sq] = promoted[c];
477 board[sq] = unpromoted[c];
481 for (c = 0; c < NO_PIECES; c++)
486 board[sq] = promoted[c];
488 board[sq] = unpromoted[c];
494 Mvboard[sq] = atoi (InPtr);
498 fgets (fname, 256, fd); /* empty */
499 fgets (fname, 256, fd); /* 9 8 7 ... */
500 fgets (fname, 256, fd); /* empty */
501 fgets (fname, 256, fd); /* p l n ... */
503 for ( side = 0; side <= 1; side++ ) {
504 fgets (fname, 256, fd);
508 Captured[side][pawn] = atoi (InPtr);
510 Captured[side][lance] = atoi (InPtr);
512 Captured[side][knight] = atoi (InPtr);
514 Captured[side][silver] = atoi (InPtr);
516 Captured[side][gold] = atoi (InPtr);
518 Captured[side][bishop] = atoi (InPtr);
520 Captured[side][rook] = atoi (InPtr);
522 Captured[side][king] = atoi (InPtr);
525 flag.regularstart = true;
527 fgets (fname, 256, fd); /* empty */
528 fgets (fname, 256, fd); /* move score ... */
529 while (fgets (fname, 256, fd))
531 struct GameRec far *g;
539 g = &GameList[GameCnt];
540 g->gmove = parser (InPtr, side, &g->fpiece);
542 g->score = atoi (InPtr);
544 g->depth = atoi (InPtr);
546 g->nodes = atol (InPtr);
548 g->time = atol (InPtr);
550 g->flags = c = atoi (InPtr);
552 g->hashkey = strtol (InPtr, (char **) NULL, 16);
554 g->hashbd = strtol (InPtr, (char **) NULL, 16);
559 for (piece = no_piece, i = 0; i < NO_PIECES; i++)
560 if (pxx[i] == *InPtr) {
565 g->color = ((*InPtr == CP[119][0]) ? white : black);
567 g->piece = (*InPtr == '+' ? promoted[piece] : unpromoted[piece]);
575 if (TimeControl.clock[black] > 0)
581 UpdateDisplay (0, 0, 1, 0);
592 short sq, i, c, f, t;
595 char empty[2] = "\n";
598 strcpy (fname, savefile);
602 ShowMessage (CP[63]);
605 if (fname[0] == '\0')
607 strcpy (fname, CP[137]);
608 if ((fd = fopen (fname, "w")) != NULL)
612 if (computer == white)
614 if (computer == black)
616 fprintf (fd, CP[37], w, b, Game50,
617 flag.force ? "force" : "");
619 fprintf (fd, CP[111], TCflag, OperatorTime);
620 fprintf (fd, CP[117],
621 TimeControl.clock[black], TimeControl.moves[black],
622 TimeControl.clock[white], TimeControl.moves[white]);
624 for (i = NO_ROWS-1; i > -1; i--)
626 fprintf (fd, "%c ", 'i' - i);
627 for (c = 0; c < NO_COLS; c++)
629 sq = i * NO_COLS + c;
631 p = is_promoted[piece] ? '+' : ' ';
632 fprintf (fd, "%c", p);
644 fprintf (fd, "%c", p);
647 for (f = i * NO_COLS; f < i * NO_COLS + NO_ROWS; f++)
648 fprintf (fd, " %d", Mvboard[f]);
652 fprintf (fd, " 9 8 7 6 5 4 3 2 1\n");
654 fprintf (fd, " p l n s g b r k\n");
655 for ( side = 0; side <= 1; side++ ) {
656 fprintf (fd, "%c", (side == black) ? 'B' : 'W');
657 fprintf (fd, " %2d", Captured[side][pawn]);
658 fprintf (fd, " %2d", Captured[side][lance]);
659 fprintf (fd, " %2d", Captured[side][knight]);
660 fprintf (fd, " %2d", Captured[side][silver]);
661 fprintf (fd, " %2d", Captured[side][gold]);
662 fprintf (fd, " %2d", Captured[side][bishop]);
663 fprintf (fd, " %2d", Captured[side][rook]);
664 fprintf (fd, " %2d", Captured[side][king]);
668 fprintf (fd, CP[126]);
669 for (i = 1; i <= GameCnt; i++)
671 struct GameRec far *g = &GameList[i];
674 t = (g->gmove & 0xFF);
675 algbr (f, t, g->flags);
677 fprintf (fd, "%c%c%-5s %6d %5d %7ld %6ld %5d 0x%08lx 0x%08lx",
679 fprintf (fd, "%c%c%-5s %6d %5d %7ld %6ld %5d 0x%08x 0x%08x",
681 (f>NO_SQUARES ? ' ' : (is_promoted[g->fpiece] ? '+' : ' ')),
683 (f>NO_SQUARES ? &mvstr[0][1] : mvstr[0]),
685 g->nodes, g->time, g->flags,
686 g->hashkey, g->hashbd);
687 if ( g->piece != no_piece )
688 fprintf (fd, " %c %s %c\n",
689 pxx[g->piece], ColorStr[g->color],
690 (is_promoted[g->piece] ? '+' : ' '));
696 ShowMessage (CP[70]);
699 /*ShowMessage ("Could not open file");*/
700 ShowMessage (CP[48]);
717 /* Enter file name */
718 ShowMessage (CP[63]);
720 if (fname[0] == '\0')
721 /* XSHOGI.position.read*/
722 strcpy (fname, CP[205]);
723 if ((fd = fopen (fname, "r")) != NULL)
726 flag.regularstart = false;
728 /* xshogi position file ... */
729 fgets (fname, 256, fd);
732 if (strcmp (fname, CP[206]))
735 /* -- empty line -- */
736 fgets (fname, 256, fd);
737 /* -- empty line -- */
738 fgets (fname, 256, fd);
739 for (i = NO_ROWS-1; i > -1; i--)
741 fgets (fname, 256, fd);
743 for (j = 0; j < NO_COLS; j++)
745 sq = i * NO_COLS + j;
750 board[sq] = no_piece;
755 for (c = 0; c < NO_PIECES; c++)
760 board[sq] = promoted[c];
762 board[sq] = unpromoted[c];
766 for (c = 0; c < NO_PIECES; c++)
771 board[sq] = promoted[c];
773 board[sq] = unpromoted[c];
782 for ( side = 0; side <= 1; side++ ) {
783 fgets (fname, 256, fd);
785 Captured[side][pawn] = atoi (InPtr);
787 Captured[side][lance] = atoi (InPtr);
789 Captured[side][knight] = atoi (InPtr);
791 Captured[side][silver] = atoi (InPtr);
793 Captured[side][gold] = atoi (InPtr);
795 Captured[side][bishop] = atoi (InPtr);
797 Captured[side][rook] = atoi (InPtr);
799 Captured[side][king] = atoi (InPtr);
801 if (fgets(fname, 256, fd) != NULL && strncmp(fname, "white", 5) == 0)
812 UpdateDisplay (0, 0, 1, 0);
826 /* Enter file name */
827 ShowMessage (CP[63]);
829 if (fname[0] == '\0')
830 /* XSHOGI.position.read*/
831 strcpy (fname, CP[205]);
832 if ((fd = fopen (fname, "w")) != NULL)
834 /* xshogi position file ... */
835 fputs("# xshogi position file -- \n", fd);
836 /* -- empty line -- */
838 /* -- empty line -- */
840 for (i = NO_ROWS-1; i > -1; i--)
843 for (j = 0; j < NO_COLS; j++)
845 sq = i * NO_COLS + j;
847 isp = is_promoted[piece];
848 *p = (isp ? '+' : ' ');
850 if ( piece == no_piece ) {
852 } else if ( color[sq] == white ) {
863 for ( side = 0; side <= 1; side++ ) {
864 sprintf(fname,"%d %d %d %d %d %d %d %d\n",
865 Captured[side][pawn],
866 Captured[side][lance],
867 Captured[side][knight],
868 Captured[side][silver],
869 Captured[side][gold],
870 Captured[side][bishop],
871 Captured[side][rook],
872 Captured[side][king]);
875 if ( computer == black ) {
876 fputs("white to play\n", fd);
878 fputs("black to play\n", fd);
898 char fname[256], sflags[4];
899 short sq, i, j, c, f, t;
904 strcpy (fname, savefile);
908 ShowMessage (CP[63]);
912 if (fname[0] == '\0')
915 if ((fd = fopen (fname, "a")) != NULL)
918 for (i = 1; i <= GameCnt; i++)
920 struct GameRec far *g = &GameList[i];
921 char mvnr[20], mvs[20];
923 sprintf(mvnr,"%d.",(i+1)/2);
927 t = (g->gmove & 0xFF);
928 algbr (f, t, g->flags);
930 /* determine move quality string */
931 if ( g->flags & goodmove )
933 if ( g->flags & badmove )
936 if ( g->flags & difficult )
940 /* determine move string */
942 sprintf(mvs,"%s%s ",&mvstr[0][1],sflags);
944 sprintf(mvs,"%c%c%c%c%c%s%s ",
945 mvstr[0][0], mvstr[0][1],
946 (g->flags & capture) ? 'x' : '-',
947 mvstr[0][2], mvstr[0][3],
948 (mvstr[0][4]=='+') ? "+" : "",
950 fprintf (fd, "%s%s%c%s",
952 (f>NO_SQUARES ? "" : (is_promoted[g->fpiece] ? "+" : "")),
962 ShowMessage (CP[70]);
965 /*ShowMessage ("Could not open file");*/
966 ShowMessage (CP[48]);
980 char fname[256], dbuf[256];
986 strcpy (fname, listfile);
990 sprintf (fname, "shogi.lst");
993 strncpy (dbuf, ctime (&when), 20);
999 /* use format "CLp16.Jan01-020304B" when patchlevel is 16,
1002 program played white */
1003 sprintf (fname, "CLp%s.%s%s-%s%s%s%c", patchlevel, dbuf + 4, dbuf + 8, dbuf + 11, dbuf + 14, dbuf + 17, ColorStr[computer][0]);
1004 /* replace space padding with 0 */
1005 for (i = 0; fname[i] != '\0'; i++)
1006 if (fname[i] == ' ')
1010 fd = fopen (fname, "w");
1013 printf (CP[219], fname);
1016 /*fprintf (fd, "gnushogi game %d\n", u);*/
1017 fprintf (fd, CP[161], version, patchlevel);
1018 fprintf (fd, CP[10]);
1019 fprintf (fd, CP[11]);
1020 for (i = 1; i <= GameCnt; i++)
1022 f = GameList[i].gmove >> 8;
1023 t = (GameList[i].gmove & 0xFF);
1024 algbr (f, t, GameList[i].flags);
1025 if(GameList[i].flags & book)
1026 fprintf (fd, "%c%c%-5s %5d Book%7ld %5d",
1027 (f>NO_SQUARES ? ' ' : (is_promoted[GameList[i].fpiece] ? '+' : ' ')),
1028 pxx[GameList[i].fpiece],
1029 (f>NO_SQUARES ? &mvstr[0][1] : mvstr[0]),
1031 GameList[i].nodes, GameList[i].time);
1033 fprintf (fd, "%c%c%-5s %5d %2d %7ld %5d",
1034 (f>NO_SQUARES ? ' ' : (is_promoted[GameList[i].fpiece] ? '+' : ' ')),
1035 pxx[GameList[i].fpiece],
1036 (f>NO_SQUARES ? &mvstr[0][1] : mvstr[0]),
1037 GameList[i].score, GameList[i].depth,
1038 GameList[i].nodes, GameList[i].time);
1043 if (computer == white)
1044 fprintf (fd, " %d %d %d %d %d %d %d\n",
1053 fprintf (fd, " %d %d %d %d %d %d %d\n",
1060 GameList[i - 1].d7);
1066 fprintf (fd, "\n\n");
1067 if (GameList[GameCnt].flags & draw)
1069 fprintf (fd, CP[54], DRAW);
1070 if ( DRAW == CP[101] )
1072 fprintf (fd, "repetition by positions ");
1073 for ( j = GameCnt-1; j >= Game50; j -= 2)
1074 if ( GameList[j].hashkey == hashkey &&
1075 GameList[j].hashbd == hashbd )
1076 fprintf (fd, "%d ", j);
1080 else if (GameList[GameCnt].score == -(SCORE_LIMIT+999))
1082 fprintf (fd, "%s\n", ColorStr[player ]);
1084 else if (GameList[GameCnt].score == (SCORE_LIMIT+998))
1086 fprintf (fd, "%s\n", ColorStr[player ^ 1]);
1098 GameList[GameCnt].flags |= badmove;
1101 GameList[GameCnt].flags |= goodmove;
1103 #ifdef EASY_OPENINGS
1105 GameList[GameCnt].flags |= difficult;
1116 * Undo the most recent half-move.
1121 f = GameList[GameCnt].gmove >> 8;
1122 t = GameList[GameCnt].gmove & 0x7F;
1123 if ( f > NO_SQUARES )
1124 { /* the move was a drop */
1125 Captured[color[t]][board[t]]++;
1126 board[t] = no_piece;
1132 if ( GameList[GameCnt].flags & promote )
1133 board[f] = unpromoted[board[t]];
1135 board[f] = board[t];
1136 color[f] = color[t];
1137 board[t] = GameList[GameCnt].piece;
1138 color[t] = GameList[GameCnt].color;
1139 if ( board[t] != no_piece )
1140 Captured[color[f]][unpromoted[board[t]]]--;
1141 if (color[t] != neutral)
1147 if (TCflag && (TCmoves>1))
1148 ++TimeControl.moves[color[f]];
1149 hashkey = GameList[GameCnt].hashkey;
1150 hashbd = GameList[GameCnt].hashbd;
1152 computer = computer ^ 1;
1153 opponent = opponent ^ 1;
1156 player = player ^ 1;
1158 UpdateDisplay (0, 0, 1, 0);
1159 if (flag.regularstart)
1169 FlagString (unsigned short flags, char *s)
1173 if ( flags & promote )
1174 strcat (s, " promote");
1175 if ( flags & dropmask )
1176 strcat (s, " drop:");
1177 if ( piece = (flags & pmask) ) {
1179 if(is_promoted[piece])
1181 s[l++] = pxx[piece];
1184 if ( flags & capture )
1185 strcat (s, " capture");
1186 if ( flags & exact )
1187 strcat (s, " exact");
1188 if ( flags & tesuji )
1189 strcat (s, " tesuji");
1190 if ( flags & check )
1191 strcat (s, " check");
1193 strcat (s, " draw");
1194 if ( flags & stupid )
1195 strcat (s, " stupid");
1196 if ( flags & questionable )
1197 strcat (s, " questionable");
1198 if ( flags & kingattack )
1199 strcat (s, " kingattack");
1201 strcat (s, " book");
1207 TestSpeed (void (*f) (short int side, short int ply, short int in_check, short int blockable),
1214 long cnt, rate, t1, t2;
1215 #ifdef HASGETTIMEOFDAY
1219 #ifdef HASGETTIMEOFDAY
1220 gettimeofday(&tv,NULL);
1221 t1 = (tv.tv_sec*100+(tv.tv_usec/10000));
1222 #elif defined THINK_C || defined MSDOS
1230 for (i = 0; i < j; i++)
1232 f (opponent, 2, -1, true);
1234 for(jj=TrPnt[2];i<TrPnt[3];jj++)if(!pick(jj,TrPnt[3]-1))break;
1238 debug_moves = false;
1240 #ifdef HASGETTIMEOFDAY
1241 gettimeofday(&tv,NULL);
1242 t2 = (tv.tv_sec*100+(tv.tv_usec/10000));
1243 #elif defined THINK_C || defined MSDOS
1248 cnt = j * (TrPnt[3] - TrPnt[2]);
1253 rate = (((et) ? ((cnt*100) / et) : 0));
1254 #ifdef DYNAMIC_ZNODES
1258 /*printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);*/
1260 printz (CP[91], cnt, rate);
1262 for (j = TrPnt[2]; j < TrPnt[3]; j++)
1264 struct leaf far *node = &Tree[j];
1265 algbr (node->f, node->t, node->flags);
1269 #if defined FIELDBONUS || defined DROPBONUS
1270 if ( node->score <= DONTUSE )
1271 fprintf (debug_eval_file, "%s %s %s %s DONTUSE",
1272 mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
1274 fprintf (debug_eval_file, "%s %s %s %s score %d INC %d",
1275 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->score,node->INCscore);
1277 if ( node->score <= DONTUSE )
1278 fprintf (debug_eval_file, "%s %s %s %s DONTUSE",
1279 mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
1281 fprintf (debug_eval_file, "%s %s %s %s score %d",
1282 mvstr[0], mvstr[1], mvstr[2], mvstr[3], node->score);
1286 FlagString(node->flags, s);
1287 fprintf(debug_eval_file,"%s",s);
1291 unsigned short hi0, hi1;
1292 mv = (node->f << 8) | node->t;
1293 if ( node->flags & promote ) mv |= 0x80;
1296 fprintf (debug_eval_file, " mv=%x hi0=%x hi1=%x",mv, hi0, hi1);
1299 fprintf (debug_eval_file, "\n");
1302 #if defined FIELDBONUS || defined DROPBONUS
1303 if ( node->score <= DONTUSE )
1304 printf ("%s %s %s %s DONTUSE %x\n",
1305 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->flags);
1307 printf ("%s %s %s %s score %d INC %d %x\n",
1308 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->score,node->INCscore,node->flags);
1310 if ( node->score <= DONTUSE )
1311 printf ("%s %s %s %s DONTUSE %x\n",
1312 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->flags);
1314 printf ("%s %s %s %s score %d %x\n",
1315 mvstr[0], mvstr[1], mvstr[2], mvstr[3],node->score,node->flags);
1325 TestPSpeed (short int (*f) (short int side), unsigned j)
1328 long cnt, rate, t1, t2;
1329 #ifdef HASGETTIMEOFDAY
1333 #ifdef HASGETTIMEOFDAY
1334 gettimeofday(&tv,NULL);
1335 t1 = (tv.tv_sec*100+(tv.tv_usec/10000));
1336 #elif defined THINK_C || defined MSDOS
1341 for (i = 0; i < j; i++)
1343 (void) f (opponent);
1345 #ifdef HASGETTIMEOFDAY
1346 gettimeofday(&tv,NULL);
1347 t2 = (tv.tv_sec*100+(tv.tv_usec/10000));
1348 #elif defined THINK_C || defined MSDOS
1358 rate = (et) ? ((cnt*100) / et) : 0;
1359 /*printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);*/
1361 printz (CP[91], cnt, rate);
1372 SetOppTime (char *s)
1379 time = &s[strlen (CP[228])];
1380 t = (int)strtol (time, &time, 10);
1381 if(*time == ':'){time++; sec=(int)strtol(time, &time,10);}
1382 m = (int)strtol (time, &time, 10);
1384 TimeControl.clock[opponent] = t;
1386 TimeControl.moves[opponent] = m;
1387 ElapsedTime (COMPUTE_AND_INIT_MODE);
1389 /* just to inform xshogi about availability of otime command */
1390 printz ("otime %d %d\n", t, m);
1397 SetMachineTime (char *s)
1402 time = &s[strlen (CP[197])];
1404 t = (int)strtol (time, &time, 10);
1405 if(*time == ':'){time++; sec=(int)strtol(time, &time,10);}
1406 m = (int)strtol (time, &time, 10);
1408 TimeControl.clock[computer] = t;
1410 TimeControl.moves[computer] = m;
1411 ElapsedTime (COMPUTE_AND_INIT_MODE);
1413 /* just to inform xshogi about availability of time command */
1414 printz ("time %d %d\n", t, m);
1419 #if defined DEBUG || defined DEBUG_EVAL
1420 void debug_position (FILE *D)
1422 short r, c, side, piece, l;
1423 fprintf (D, "\n current board is\n\n");
1424 for (piece = pawn; piece <= king; piece++)
1425 if (c = Captured[white][piece])
1426 fprintf(D, "%i%c ",c,pxx[piece]);
1428 for (c = 0; c < NO_COLS; c++)
1429 fprintf (D, " %d", PawnCnt[white][c]);
1430 fprintf (D, "\n\n");
1431 for (r = NO_ROWS-1; r >= 0; r--)
1433 for (c = 0; c <= NO_COLS-1; c++)
1436 pc = (is_promoted[board[l]] ? '+' : ' ');
1437 if (color[l] == neutral)
1439 else if (color[l] == black)
1440 fprintf (D, "%c%c", pc, qxx[board[l]]);
1442 fprintf (D, "%c%c", pc, pxx[board[l]]);
1447 for (c = 0; c < NO_COLS; c++)
1448 fprintf (D, " %d", PawnCnt[black][c]);
1450 for (piece = pawn; piece <= king; piece++)
1451 if (c = Captured[black][piece])
1452 fprintf(D, "%i%c ",c,pxx[piece]);
1460 InputCommand (char *command)
1463 * Process the users command. If easy mode is OFF (the computer is thinking
1464 * on opponents time) and the program is out of book, then make the 'hint'
1465 * move on the board and call SelectMove() to find a response. The user
1466 * terminates the search by entering ^C (quit siqnal) before entering a
1467 * command. If the opponent does not make the hint move, then set Sdepth to
1473 short have_shown_prompt = false;
1474 short ok, done, is_move = false;
1478 ok = flag.quit = done = false;
1481 if(TTadd > ttbllimit)ZeroTTable();
1483 if (hint > 0 && !flag.easy && !flag.force )
1485 /* A hint move for the player is available.
1486 Compute a move for the oppnonent in background mode assuming
1487 that the hint move will be selected by the player. */
1488 ft = time0; /* Save reference time for the player. */
1490 algbr ((short) hint >> 8, (short) hint & 0xff, false);
1491 strcpy (s, mvstr[0]);
1497 extern unsigned short int PrVar[];
1498 extern struct leaf far *root;
1499 D = fopen ("/tmp/DEBUGA", "a+");
1500 fprintf (D, "score = %d\n", root->score);
1501 fprintf (D, "inout move is %s\n", s);
1502 for (r = 1; PrVar[r]; r++)
1504 algbr (PrVar[r] >> 8, PrVar[r] & 0xff, (short) 0);
1505 fprintf (D, " %s", mvstr[0]);
1511 if (flag.post) GiveHint ();
1513 /* do the hint move */
1514 if (VerifyMove (s, VERIFY_AND_TRY_MODE, &mv))
1518 #ifdef QUIETBACKGROUND
1525 have_shown_prompt = true;
1526 #endif /* QUIETBACKGROUND */
1527 /* Start computing a move until the search is interrupted. */
1528 #ifdef INTERRUPT_TEST
1531 /* would love to put null move in here */
1532 /* after we make the hint move make a 2 ply search with both plys our moves */
1533 /* think on opponents time */
1534 SelectMove (computer, BACKGROUND_MODE);
1535 #ifdef INTERRUPT_TEST
1536 ElapsedTime(COMPUTE_INTERRUPT_MODE);
1538 printf("searching not terminated by interrupt!\n");
1540 printf("elapsed time from interrupt to terminating search: %ld\n",it);
1542 /* undo the hint and carry on */
1543 VerifyMove (s, UNMAKE_MODE, &mv);
1546 time0 = ft; /* Restore reference time for the player. */
1548 while (!(ok || flag.quit || done))
1551 #ifdef QUIETBACKGROUND
1552 if (!have_shown_prompt)
1554 #endif /* QUIETBACKGROUND */
1561 #ifdef QUIETBACKGROUND
1563 have_shown_prompt = false;
1564 #endif /* QUIETBACKGROUND */
1565 if ( command == NULL )
1568 s[0] = sx[0] = '\0';
1573 #if defined MSDOS || defined THINK_C
1575 eof = ( gets (sx) == NULL );
1577 eof = ( getstr (sx) == ERR );
1583 strcpy (sx, command);
1586 sscanf (sx, "%s", s);
1591 if (strcmp (s, CP[131]) == 0) /*bd*/
1597 UpdateDisplay (0, 0, 1, 0);
1602 else if (strcmp (s, "post") == 0)
1603 flag.post = !flag.post;
1604 else if (strcmp (s, CP[129]) == 0) /* noop */ ; /*alg*/
1605 else if ((strcmp (s, CP[180]) == 0) || (strcmp (s, CP[216]) == 0)) /* quit exit*/
1608 else if (strcmp (s, CP[178]) == 0) /*post*/
1610 flag.post = !flag.post;
1613 else if ((strcmp (s, CP[191]) == 0) || (strcmp (s, CP[154]) == 0)) /*set edit*/
1616 else if (strcmp (s, CP[190]) == 0) /*setup*/
1619 else if (strcmp (s, CP[156]) == 0) /*first*/
1623 else if (strcmp (s, CP[162]) == 0) /*go*/
1627 if (computer == black)
1638 else if (strcmp (s, CP[166]) == 0) /*help*/
1640 else if (strcmp (s, CP[221]) == 0) /*material*/
1641 flag.material = !flag.material;
1642 else if (strcmp (s, CP[157]) == 0) /*force*/
1644 {flag.force = true; flag.bothsides = false;}
1646 {flag.force = !flag.force; flag.bothsides = false;}
1648 else if (strcmp (s, CP[134]) == 0) /*book*/
1649 Book = Book ? 0 : BOOKFAIL;
1650 else if (strcmp (s, CP[172]) == 0) /*new*/
1653 UpdateDisplay (0, 0, 1, 0);
1655 else if (strcmp (s, CP[171]) == 0) /*list*/
1657 else if (strcmp (s, CP[169]) == 0 || strcmp (s, CP[217]) == 0) /*level clock*/
1659 else if (strcmp (s, CP[165]) == 0) /*hash*/
1660 flag.hash = !flag.hash;
1661 else if (strcmp (s, CP[227]) == 0) /*gamein*/
1662 flag.gamein = !flag.gamein;
1663 else if (strcmp (s, CP[226]) == 0) /*beep*/
1664 flag.beep = !flag.beep;
1665 else if (strcmp (s, CP[197]) == 0) /*time*/
1666 { SetMachineTime (sx); }
1667 else if (strcmp (s, CP[228]) == 0) /*otime*/
1668 { SetOppTime (sx); }
1669 else if (strcmp (s, CP[33]) == 0) /*Awindow*/
1670 ChangeAlphaWindow ();
1671 else if (strcmp (s, CP[39]) == 0) /*Bwindow*/
1672 ChangeBetaWindow ();
1673 else if (strcmp (s, CP[183]) == 0) /*rcptr*/
1674 flag.rcptr = !flag.rcptr;
1675 else if (strcmp (s, CP[168]) == 0) /*hint*/
1677 else if (strcmp (s, CP[135]) == 0) /*both*/
1679 flag.bothsides = !flag.bothsides;
1682 ElapsedTime (COMPUTE_AND_INIT_MODE);
1683 SelectMove (opponent, FOREGROUND_MODE);
1686 else if (strcmp (s, CP[185]) == 0) /*reverse*/
1688 flag.reverse = !flag.reverse;
1690 UpdateDisplay (0, 0, 1, 0);
1692 else if (strcmp (s, CP[195]) == 0) /*switch*/
1694 computer = computer ^ 1;
1695 opponent = opponent ^ 1;
1696 xwndw = (computer == black) ? WXWNDW : BXWNDW;
1701 else if (strcmp (s, CP[203]) == 0) /*black*/
1710 * ok = true; don't automatically start with black command
1713 else if (strcmp (s, CP[133]) == 0) /*white*/
1722 * ok = true; don't automatically start with white command
1725 else if (strcmp (s, CP[201]) == 0 && GameCnt > 0) /*undo*/
1729 else if (strcmp (s, CP[184]) == 0 && GameCnt > 1) /*remove*/
1735 else if (strcmp (s, CP[207]) == 0) /*xget*/
1737 else if (strcmp (s, "xsave") == 0) /*xsave*/
1739 else if (strcmp (s, "bsave") == 0) /*bsave*/
1742 #ifdef EASY_OPENINGS
1743 else if (strcmp (s, "?") == 0 || strcmp (s, "!") == 0 || strcmp (s, "~") == 0)
1745 else if (strcmp (s, "?") == 0 || strcmp (s, "!") == 0)
1748 else if (strcmp (s, CP[160]) == 0) /*get*/
1750 else if (strcmp (s, CP[189]) == 0) /*save*/
1752 else if (strcmp (s, CP[151]) == 0) /*depth*/
1753 ChangeSearchDepth ();
1755 else if (strcmp (s, CP[147]) == 0) /*debuglevel*/
1758 else if (strcmp (s, CP[164]) == 0) /*hashdepth*/
1760 else if (strcmp (s, CP[182]) == 0) /*random*/
1762 else if (strcmp (s, CP[229]) == 0) /*hard*/
1764 else if (strcmp (s, CP[152]) == 0) /*easy*/
1765 flag.easy = !flag.easy;
1766 else if (strcmp (s, CP[230]) == 0) /*tsume*/
1767 flag.tsume = !flag.tsume;
1768 else if (strcmp (s, CP[143]) == 0) /*contempt*/
1770 else if (strcmp (s, CP[209]) == 0) /*xwndw*/
1772 else if (strcmp (s, CP[186]) == 0) /*rv*/
1775 UpdateDisplay (0, 0, 1, 0);
1777 else if (strcmp (s, CP[145]) == 0) /*coords*/
1779 flag.coords = !flag.coords;
1780 UpdateDisplay (0, 0, 1, 0);
1782 else if (strcmp (s, CP[193]) == 0) /*stars*/
1784 flag.stars = !flag.stars;
1785 UpdateDisplay (0, 0, 1, 0);
1788 else if (strcmp (s, CP[5]) == 0) /*moves*/
1791 debug_eval = ((debug_eval_file = fopen(EVALFILE,"w")) != NULL);
1794 if ( GameCnt > 0 ) {
1795 extern unsigned short int PrVar[MAXDEPTH];
1796 SwagHt = (GameList[GameCnt].gmove == PrVar[1]) ? PrVar[2] : 0;
1800 ShowMessage (CP[108]); /*test movelist*/
1801 temp = generate_move_flags;
1802 generate_move_flags = true;
1803 TestSpeed (MoveList, 1);
1804 generate_move_flags = temp;
1805 ShowMessage (CP[107]); /*test capturelist*/
1806 TestSpeed (CaptureList, 1);
1807 ShowMessage (CP[85]); /*test score position*/
1808 ExaminePosition(opponent);
1809 TestPSpeed (ScorePosition, 1);
1811 if ( debug_eval ) fclose(debug_eval_file);
1815 else if (strcmp (s, CP[196]) == 0) /*test*/
1818 ShowMessage (CP[108]);/*test movelist*/
1819 TestSpeed (MoveList, 2000);
1820 ShowMessage (CP[107]);/*test capturelist*/
1821 TestSpeed (CaptureList, 3000);
1822 ShowMessage (CP[85]);/*test score position*/
1823 ExaminePosition(opponent);
1824 TestPSpeed (ScorePosition, 1500);
1826 ShowMessage (CP[108]);/*test movelist*/
1827 TestSpeed (MoveList, 20000);
1828 ShowMessage (CP[107]);/*test capturelist*/
1829 TestSpeed (CaptureList, 30000);
1830 ShowMessage (CP[85]);/*test score position*/
1831 ExaminePosition(opponent);
1832 TestPSpeed (ScorePosition, 15000);
1836 else if (strcmp (s, "eval") == 0) /*eval*/
1839 if ( debug_eval_file = fopen(EVALFILE,"w") ) {
1841 ExaminePosition(opponent);
1842 fprintf (debug_eval_file, "\nscoring for %s to move...\n\n",
1844 ScorePosition (player);
1845 fclose (debug_eval_file);
1849 else if (strcmp (s, "debug_eval") == 0) /*debug_eval*/
1853 fclose (debug_eval_file);
1858 debug_eval_file = fopen(EVALFILE,"w");
1859 debug_eval = (debug_eval_file != NULL);
1862 else if (strcmp (s, "pattern") == 0) /*pattern*/
1865 if ( debug_eval_file = fopen(EVALFILE,"w") ) {
1867 for (side=black; side<=white; side++) {
1868 short s = ScorePatternDistance (side);
1869 fprintf (debug_eval_file, "\npattern distance score for %s is %d\n\n",
1872 fclose (debug_eval_file);
1876 #endif /* DEBUG_EVAL */
1878 if (strcmp (s, CP[179]) == 0) /*p*/
1880 else if (strcmp (s, CP[148]) == 0) /*debug*/
1887 else if ( ok = VerifyMove (s, VERIFY_AND_MAKE_MODE, &mv) )
1889 /* check for repetition */
1890 short int rpt = repetition();
1894 GameList[GameCnt].flags |= draw;
1904 ElapsedTime (COMPUTE_AND_INIT_MODE);
1908 computer = opponent;
1909 opponent = computer ^ 1;
1912 /* add remaining time in milliseconds for xshogi */
1914 printz ("%d. %s %ld\n", ++mycnt2, s, TimeControl.clock[player]*10);
1915 #ifdef notdef /* optional pass best line to frontend with move */
1917 if (flag.post && !flag.mate)
1921 printz (" %6d ", MSCORE);
1922 for (i = 1; MV[i] > 0; i++)
1924 algbr ((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
1925 printz ("%5s ", mvstr[0]);
1932 signal (SIGINT, TerminateSearch);
1933 #if !defined MSDOS && !defined THINK_C && !defined BORLAND_CPP
1934 signal (SIGQUIT, TerminateSearch);
1940 #if defined NOFIONREAD
1949 #ifdef HASGETTIMEOFDAY
1951 ElapsedTime (ElapsedTime_mode iop)
1955 * Determine the time that has passed since the search was started. If the
1956 * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
1957 * to true which will terminate the search.
1958 * iop = COMPUTE_MODE calculate et, bump ETnodes
1959 * iop = COMPUTE_AND_INIT_MODE calculate et, set timeout if time exceeded,
1960 * set reference time
1971 if (i = ioctl ((int) 0, FIONREAD, &nchar))
1973 perror ("FIONREAD");
1975 "You probably have a non-ANSI <ioctl.h>; see README. %d %d %x\n",
1976 i, errno, FIONREAD);
1984 flag.bothsides = false;
1992 flag.bothsides = false;
1995 gettimeofday(&tv,NULL);
1996 current_time = tv.tv_sec*100 + (tv.tv_usec/10000);
1997 #ifdef INTERRUPT_TEST
1998 if ( iop == INIT_INTERRUPT_MODE )
2000 itime0 = current_time;
2002 else if ( iop == COMPUTE_INTERRUPT_MODE )
2004 it = current_time - itime0;
2009 et = current_time - time0;
2010 ETnodes = NodeCnt + znodes;
2013 #ifdef INTERRUPT_TEST
2014 printf("elapsed time %ld not positive\n", et);
2018 if (iop == COMPUTE_AND_INIT_MODE)
2020 if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
2021 flag.timeout = true;
2022 time0 = current_time;
2025 #ifdef QUIETBACKGROUND
2027 #endif /* QUIETBACKGROUND */
2036 ElapsedTime (ElapsedTime_mode iop)
2040 * Determine the time that has passed since the search was started. If the
2041 * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
2042 * to true which will terminate the search. iop = 0 calculate et bump ETnodes
2043 * iop = 1 calculate et set timeout if time exceeded, calculate et
2053 if (i = ioctl ((int) 0, FIONREAD, &nchar))
2055 perror ("FIONREAD");
2057 "You probably have a non-ANSI <ioctl.h>; see README. %d %d %x\n",
2058 i, errno, FIONREAD);
2066 flag.bothsides = false;
2074 flag.bothsides = false;
2077 #if defined THINK_C || defined MSDOS
2078 et = ((current_time = clocktime()) - time0);
2080 et = ((current_time = time ((long *) 0)) - time0) * 100;
2082 #ifdef INTERRUPT_TEST
2083 if ( iop == INIT_INTERRUPT_MODE )
2085 itime0 = current_time;
2087 else if ( iop == COMPUTE_INTERRUPT_MODE )
2089 it = current_time - itime0;
2094 ETnodes = NodeCnt + znodes;
2097 #ifdef INTERRUPT_TEST
2098 printf("elapsed time %ld not positive\n", et);
2102 if (iop == COMPUTE_AND_INIT_MODE)
2104 if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
2105 flag.timeout = true;
2106 time0 = current_time;
2109 #ifdef QUIETBACKGROUND
2111 #endif /* QUIETBACKGROUND */
2118 SetTimeControl (void)
2122 TimeControl.moves[black] = TimeControl.moves[white] = TCmoves;
2123 TimeControl.clock[black] += 6000L * TCminutes + TCseconds * 100;
2124 TimeControl.clock[white] += 6000L * TCminutes + TCseconds * 100;
2128 TimeControl.moves[black] = TimeControl.moves[white] = 0;
2129 TimeControl.clock[black] = TimeControl.clock[white] = 0;
2131 flag.onemove = (TCmoves == 1);
2133 ElapsedTime (COMPUTE_AND_INIT_MODE);
2138 TerminateChess (int sig)