home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / RiscPc / jeux / ArcBoard004.arc / !GNUChessX / src / misc / gnuan_c < prev    next >
Text File  |  1995-07-02  |  40KB  |  1,778 lines

  1. /*
  2.  * gnuan.c - Analysis interface for gnuchess.
  3.  * 
  4.  * Copyright (c) 1988,1989,1990 John Stanback Copyright (c) 1992 Free Software
  5.  * Foundation
  6.  * 
  7.  * This file is part of GNU CHESS.
  8.  * 
  9.  * GNU Chess is free software; you can redistribute it and/or modify it under
  10.  * the terms of the GNU General Public License as published by the Free
  11.  * Software Foundation; either version 2, or (at your option) any later
  12.  * version.
  13.  * 
  14.  * GNU Chess is distributed in the hope that it will be useful, but WITHOUT ANY
  15.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16.  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  17.  * details.
  18.  * 
  19.  * You should have received a copy of the GNU General Public License along with
  20.  * GNU Chess; see the file COPYING.  If not, write to the Free Software
  21.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. /*
  25.  * This is a front end for a chess analysis program.  It takes a file of
  26.  * moves in algebraic notation and creates a file containing each move that
  27.  * was made, the move it would have made, the score it would give itself
  28.  * after making the move it recommended, and the depth it searched for the
  29.  * move.
  30.  * 
  31.  * This is a modification of nondsp.c.  I have cut out code that was not needed
  32.  * for this application such as the help and edit functions.  Most of the
  33.  * modifications were done in InputCommand.
  34.  */
  35.  
  36. /*
  37.  * This file will generate two different analysis programs.  One is meant to
  38.  * be run as a background process inwhich the in and out files are
  39.  * predefined. The other is meant to be run in the foreground where it will
  40.  * prompt you for the name of the file with the game in it, the maximum depth
  41.  * the search should be conducted to and the time limit per move.  It would
  42.  * be nice to be able to give these parameters on the command line, but that
  43.  * would mean changing main which is in the gnuchess.c file.
  44.  * 
  45.  * For each move it will analyse the move until either it has run out of time or
  46.  * it has reached the maximum depth.
  47.  * 
  48.  * To build the version for background processing define BACKGROUND_ANALYSIS
  49.  * either at the top of this file, or in compilation.  The files and depth
  50.  * used are defined below.  They are MAX_DEPTH, MAX_TIME, OUT_FILE, IN_FILE
  51.  * and PROG_FILE.  The PROG_FILE is a file that will be updated as each move
  52.  * is analysed so you can check its progress.  This is only updated when
  53.  * running the BACKGROUND_ANALYSIS version.  In the version where the
  54.  * filename and depth are entered at runtime, the output goes to stdout.
  55.  */
  56.  
  57. #define BACKGROUND_ANALYSIS 0 
  58.  
  59. #define MAX_DEPTH  MAXDEPTH
  60. #define MAX_MINUTE 0
  61. #define MAX_SECOND 20
  62. #define OUT_FILE   "gnuan.out"
  63. #define IN_FILE    "gnuan.in"
  64. #define PROG_FILE  "gnuan.prog"
  65.  
  66.  
  67. #include <ctype.h>
  68. #include <signal.h>
  69. #include <fcntl.h>
  70. #ifdef MSDOS
  71. #include <dos.h>
  72. #include <conio.h>
  73. #include <stdlib.h>
  74. #include <string.h>
  75. #include <io.h>
  76. #else
  77. #include <sys/param.h>
  78. #include <sys/types.h>
  79. #include <sys/file.h>
  80. #ifndef AMIGADOS
  81. #include <sys/ioctl.h>
  82. #endif
  83. void TerminateSearch (int), Die (int);
  84.  
  85. #define O_BINARY 0
  86.  
  87. #endif /* MSDOS */
  88.  
  89. #include "gnuchess.h"
  90. #include "ttable.h"
  91. #include "ataks.h"
  92. #undef rxx
  93. #undef cxx
  94. #undef scanz
  95. #undef printz
  96.  
  97. #define rxx "12345678"
  98. #define cxx "abcdefgh"
  99. #define scanz scanf
  100. #define printz printf
  101. extern SHORT board[64], color[64], Mvboard[64];
  102. extern CHAR *ColorStr[2];
  103. SHORT debuglevel = 0;
  104. int mycnt1, mycnt2;
  105. char mvstr[5][7];
  106.  
  107. static FILE *fpin;
  108. static FILE *fpout;
  109. int samedepth = false;
  110. CHAR *DRAW;
  111. UTSHORT MV[MAXDEPTH+1];
  112. enum
  113.   {
  114.       XBOARD, GNUCHESS, PGN, OTHER
  115.   }
  116. InFileType;
  117. CHAR InBuf[256];
  118.  
  119. #ifdef BACKGROUND_ANALYSIS
  120. static FILE *fpprog;
  121.  
  122. #endif
  123. static CHAR white_actual_move[20];
  124. static CHAR black_actual_move[20];
  125. static CHAR suggest_move[20];
  126. static CHAR suggest_move1[20];
  127. static CHAR suggest_move2[20];
  128. static CHAR suggest_move3[20];
  129.     int total_moves[2];
  130.     int same_moves[2];
  131. static int sdw, sdb;
  132. static int print_score;
  133. int tmpscore;
  134. static int current_depth;
  135. static int current_score;
  136. static int enable_update_display = 0;
  137. static CHAR GNUANmove[400][16];    /* moves for this game strings */
  138. static SHORT GNUANsd[400];    /* search depth for each move */
  139. static SHORT GNUANnext;        /*                               */
  140. static SHORT GNUANhint;        /*                               */
  141. static SHORT GNUANdepth;    /*Search depth override         */
  142. static SHORT GNUANcurrmove;    /* current move within base  */
  143. static SHORT GNUANbasemove;    /* base for curr move set    */
  144. static SHORT GNUANmovecnt;    /* movecnt within base frame        */
  145. static SHORT GNUANnextstop = 0;    /*loop control proceed to this move */
  146. SHORT GNUANtop;            /* # movees in adjlist   */
  147. SHORT GNUANtopLim = 0;            /* # movees in adjlist   */
  148. static unsigned short GNUANadjlist[20];        /*moves to not use       */
  149. static CHAR GNUANinbuf[256];    /* input buffer     */
  150. struct
  151.   {
  152.       SHORT board[64];
  153.       SHORT color[64];
  154.       SHORT mvboard[64];
  155.       SHORT currmove;
  156.       SHORT movecnt;
  157.       SHORT basemove;
  158.       SHORT moveno;
  159.   }
  160. GNUANsave[20];
  161. SHORT GNUANsavedepth;
  162. static enum INenum
  163.   {
  164.       file, keyboard
  165.   }
  166. GNUANinput;
  167. int move_number = 1;
  168.  
  169. #ifdef notdef
  170. GNUANlist (SHORT mv[])
  171. {
  172.     SHORT B[64], C[64];
  173.     SHORT from, to, i;
  174.     SHORT plain = false;
  175.     memcpy (B, board, sizeof (B));
  176.     memcpy (C, color, sizeof (C));
  177.  
  178.     for (i = 1; mv[i] != 0; i++)
  179.       {
  180.       from = mv[i] >> 8;
  181.       to = mv[i] & 0xff;
  182.       algbr (from, to, 0);
  183.       if(plain) fprintf (fpout, "%5s ", mvstr[0]);
  184.       else fprintf (fpout, "%5s ", mvstr[1]);
  185.       if (mv[i] == WHITECASTLE)
  186.         {
  187.         /* castle short */ board[5] = board[7];
  188.         board[7] = no_piece;
  189.         color[5] = color[7];
  190.         color[7] = neutral;
  191.         }
  192.       else if (mv[i] == LONGWHITECASTLE)
  193.         {
  194.         /* castle short */ board[3] = board[0];
  195.         board[0] = no_piece;
  196.         color[3] = color[0];
  197.         color[0] = neutral;
  198.         }
  199.       else if (mv[i] == BLACKCASTLE)
  200.         {
  201.         /* castle short */ board[60] = board[63];
  202.         board[63] = no_piece;
  203.         color[60] = color[63];
  204.         color[63] = neutral;
  205.         }
  206.       else if (mv[i] == LONGBLACKCASTLE)
  207.         {
  208.         /* castle long */ board[59] = board[56];
  209.         board[56] = no_piece;
  210.         color[59] = color[56];
  211.         color[56] = neutral;
  212.         }
  213. /* could it be en-passant or promote */
  214.       else if (board[from] == pawn && color[from] == black)
  215.         {
  216.         if (row (to) == 0)
  217.           {        /* promote */
  218.                  plain = true;
  219.           }
  220.         else if ((row (from) == 3 && row(to) == 2) && 
  221.             ((column(to) == (column(from) -1)) || 
  222.              (column(to) == column(from) +1))
  223.             && board[to] == no_piece
  224.             && board[to + 8] == pawn
  225.             && color[to + 8] == white)
  226.           {        /* possible en-passant */
  227.              board[to+8] = no_piece;
  228.              color[to+8] = neutral;
  229.           }
  230.         }
  231.       else if (board[from] == pawn && color[from] == white)
  232.         {
  233.         if (row (to) == 7)
  234.           {        /* promote */
  235.                  plain=true;
  236.           }
  237.         else if ((row (from) == 4 && row(to) == 5) && 
  238.             ((column(to) == (column(from) -1)) || 
  239.              (column(to) == column(from) +1))
  240.             && board[to] == no_piece
  241.             && board[to - 8] == pawn
  242.             && color[to - 8] == black)
  243.           {        /* possible en-passant */
  244.              board[to+8] = no_piece;
  245.              color[to+8] = neutral;
  246.           }
  247.         }
  248.  
  249.       board[to] = board[from];
  250.       color[to] = color[from];
  251.       board[from] = no_piece;
  252.       color[from] = neutral;
  253.       }
  254.     memcpy (board, B, sizeof (B));
  255.     memcpy (color, C, sizeof (C));
  256.     return(0);
  257. }
  258. #endif
  259.  
  260. void
  261. GNUANadj ()
  262. {
  263.     int i, b;
  264.     for (i = 0; i < GNUANtop; i++)
  265.       {
  266.       for (b = TrPnt[1]; b < (unsigned) TrPnt[2]; b++)
  267.         {
  268.         if (((Tree[b].f << 8) | Tree[b].t) == GNUANadjlist[i])
  269.           {
  270.               Tree[b].score = DONTUSE;
  271.               break;
  272.           }
  273.         }
  274.       }
  275. }
  276. void
  277. Initialize (void)
  278. {
  279.     mycnt1 = mycnt2 = 0;
  280. }
  281.  
  282. void
  283. ExitChess (void)
  284. {
  285.     ListGame ();
  286.     exit (0);
  287. }
  288.  
  289. #ifndef MSDOS            /* never called!!! */
  290. void
  291. Die (int sig)
  292. {
  293.     ExitChess ();
  294. }
  295.  
  296. #endif /* MSDOS */
  297.  
  298. void
  299. TerminateSearch (int sig)
  300. {
  301. #ifdef MSDOS
  302.     sig++;            /* shut up the compiler */
  303. #endif /* MSDOS */
  304.     if (!flag.timeout)
  305.     flag.musttimeout = true;
  306.     flag.bothsides = false;
  307. }
  308.  
  309. void
  310. algbr (SHORT f, SHORT t, SHORT flag)
  311.  
  312.  
  313. /*
  314.  * Generate move strings in different formats.
  315.  */
  316.  
  317. {
  318.     int m3p;
  319.  
  320.     if (f != t)
  321.       {
  322.       /* algebraic notation */
  323.       mvstr[0][0] = cxx[column (f)];
  324.       mvstr[0][1] = rxx[row (f)];
  325.       mvstr[0][2] = cxx[column (t)];
  326.       mvstr[0][3] = rxx[row (t)];
  327.       mvstr[4][0] = mvstr[0][4] = mvstr[3][0] = '\0';
  328.       if (((mvstr[1][0] = pxx[board[f]]) == CP[2][1]) || (flag & promote))
  329.         {
  330.         if (mvstr[0][0] == mvstr[0][2])        /* pawn did not eat */
  331.           {
  332.               mvstr[2][0] = mvstr[1][0] = mvstr[0][2];    /* to column */
  333.               mvstr[2][1] = mvstr[1][1] = mvstr[0][3];    /* to row */
  334.               m3p = 2;
  335.           }
  336.         else
  337.             /* pawn ate */
  338.           {
  339.               mvstr[2][0] = mvstr[1][0] = mvstr[0][0];    /* column */
  340.               mvstr[2][1] = mvstr[1][1] = mvstr[0][2];    /* to column */
  341.               mvstr[2][2] = mvstr[0][3];
  342.               m3p = 3;    /* to row */
  343.           }
  344.         if (flag & promote)
  345.           {
  346.               mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  347.               mvstr[0][5] = mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[3][0] = '\0';
  348. #ifdef CHESSTOOL
  349.               mvstr[3][0] = mvstr[0][0];    /* Allow e7e8 for chesstool */
  350.               mvstr[3][1] = mvstr[0][1];
  351.               mvstr[3][2] = mvstr[0][2];
  352.               mvstr[3][3] = mvstr[0][3];
  353.               mvstr[3][4] = '\0';
  354. #endif
  355.           }
  356.         else
  357.             mvstr[2][m3p] = mvstr[1][2] = '\0';
  358.         }
  359.       else
  360.           /* not a pawn */
  361.         {
  362.         mvstr[2][0] = mvstr[1][0];
  363.         mvstr[2][1] = mvstr[0][1];
  364.         mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
  365.         mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
  366.         mvstr[2][4] = mvstr[1][3] = '\0';
  367.         strcpy (mvstr[3], mvstr[2]);
  368.         mvstr[3][1] = mvstr[0][0];
  369.         mvstr[4][0] = mvstr[1][0];
  370.         strcpy (&mvstr[4][1], mvstr[0]);
  371.         if (flag & cstlmask)
  372.           {
  373.               if (t > f)
  374.             {
  375.                 strcpy (mvstr[1], mvstr[0]);
  376.                 strcpy (mvstr[0], CP[5]);
  377.                 strcpy (mvstr[2], CP[7]);
  378.                 strcpy (mvstr[3], "O-O");
  379.             }
  380.               else
  381.             {
  382.                 strcpy (mvstr[1], mvstr[0]);
  383.                 strcpy (mvstr[0], CP[6]);
  384.                 strcpy (mvstr[2], CP[8]);
  385.                 strcpy (mvstr[3], "O-O-O");
  386.             }
  387.           }
  388.         }
  389.       }
  390.     else
  391.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = mvstr[4][0] = '\0';
  392. }
  393.  
  394. int
  395. strxcmp (char *sx, char *sbase)
  396.  
  397. /*
  398.  * Compare strings sx and sbase, but ignore any 'x' characters found in sx.
  399.  * This kludge lets gnuan parse notation with "x" for capture.
  400.  */
  401. {
  402.     for (;;)
  403.       {
  404.       if (*sx == 'x')
  405.           sx++;
  406.       if (*sx == '\0')
  407.         {
  408.         if (*sbase == '\0')
  409.             return 0;
  410.         else
  411.             return -1;
  412.         }
  413.       if (*sx < *sbase)
  414.           return -1;
  415.       else if (*sx > *sbase)
  416.           return 1;
  417.       sx++;
  418.       sbase++;
  419.       }
  420. }
  421.  
  422.  
  423.  
  424. int
  425. VerifyMove (CHAR * s, SHORT iop, UTSHORT * mv)
  426.  
  427. /*
  428.  * Compare the string 's' to the list of legal moves available for the
  429.  * opponent. If a match is found, make the move on the board.
  430.  */
  431.  
  432. {
  433.     static SHORT pnt, tempb, tempc, tempsf, tempst, cnt;
  434.     static struct leaf xnode;
  435.     struct leaf *node;
  436.  
  437.     *mv = 0;
  438.     if (iop == 2)
  439.       {
  440.       UnmakeMove (computer, &xnode, &tempb, &tempc, &tempsf, &tempst);
  441.       return (false);
  442.       }
  443.     cnt = 0;
  444.     MoveList (computer, 2);
  445.     pnt = TrPnt[2];
  446.     while (pnt < TrPnt[3])
  447.       {
  448.       node = &Tree[pnt++];
  449.       algbr (node->f, node->t, (SHORT) node->flags);
  450.       if (strxcmp (s, mvstr[0]) == 0 || strxcmp (s, mvstr[1]) == 0 ||
  451.           strxcmp (s, mvstr[2]) == 0 || strxcmp (s, mvstr[3]) == 0)
  452.         {
  453.         cnt++;
  454.         xnode = *node;
  455.         }
  456.       }
  457.     if (cnt == 1)
  458.       {
  459.       MakeMove (computer, &xnode, &tempb, &tempc, &tempsf, &tempst);
  460.       if (SqAtakd (PieceList[computer][0], opponent))
  461.         {
  462.         UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  463.         printz ("Illegal move\n");
  464.         return (false);
  465.         }
  466.       else
  467.         {
  468.         if (iop == 1)
  469.             return (true);
  470.  
  471.         /*
  472.          * UpdateDisplay (xnode.f, xnode.t, 0, (SHORT) xnode.flags);
  473.          */
  474.         if ((board[xnode.t] == pawn)
  475.             || (xnode.flags & capture)
  476.             || (xnode.flags & cstlmask))
  477.           {
  478.               Game50 = GameCnt;
  479.               ZeroRPT ();
  480.           }
  481.         GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  482.         GameList[GameCnt].nodes = 0;
  483.         ElapsedTime (1);
  484.         GameList[GameCnt].time = (SHORT) et;
  485.         TimeControl.clock[opponent] -= et;
  486.         --TimeControl.moves[opponent];
  487.         *mv = (xnode.f << 8) | xnode.t;
  488.         algbr (xnode.f, xnode.t, false);
  489.         return (true);
  490.         }
  491.       }
  492. #ifdef CHESSTOOL
  493.     printz ("Illegal move\n");
  494. #else
  495.     if (cnt > 1)
  496.     ShowMessage ("Ambiguous Move!");
  497. #endif
  498.     if (cnt == 0)
  499.       {
  500.       pnt = TrPnt[2];
  501.       while (pnt < TrPnt[3])
  502.         {
  503.         node = &Tree[pnt++];
  504.         algbr (node->f, node->t, (SHORT) node->flags);
  505.         printf ("%s -> %s %s %s %s\n", s, mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
  506.         }
  507.       }
  508.     return (false);
  509. }
  510.  
  511. void
  512. help (void)
  513. {
  514. }
  515.  
  516. void
  517. EditBoard (void)
  518.  
  519. /*
  520.  * Set up a board position. Pieces are entered by typing the piece followed
  521.  * by the location. For example, Nf3 will place a knight on square f3.
  522.  */
  523.  
  524. {
  525. }
  526.  
  527. void
  528. SetupBoard (void)
  529.  
  530. /*
  531.  * Compatibility with Unix chess and the nchesstool. Set up a board position.
  532.  * Eight lines of eight characters are used to setup the board. a8-h8 is the
  533.  * first line. Black pieces are  represented  by  uppercase characters.
  534.  */
  535.  
  536. {
  537. }
  538.  
  539. void
  540. ShowDepth (CHAR ch)
  541. {
  542. #ifdef MSDOS
  543.     ch++;            /* shut up the compiler */
  544. #endif /* MSDOS */
  545. }
  546.  
  547. void
  548. ShowLine (UTSHORT * bstline)
  549. {
  550.     register int i;
  551.  
  552.     for (i = 1; bstline[i] > 0; i++)
  553.       {
  554.       if ((i > 1) && (i % 8 == 1))
  555.           printf ("\n                          ");
  556.       algbr ((SHORT) (bstline[i] >> 8), (SHORT) (bstline[i] & 0xFF), false);
  557.       printf ("%5s ", mvstr[0]);
  558.       }
  559.     printf ("\n");
  560. }
  561.  
  562.  
  563. void
  564. ShowResults (SHORT score, UTSHORT * bstline, CHAR ch)
  565. {
  566.     int i;
  567.  
  568.     if (flag.post)
  569.       {
  570.       ElapsedTime (2);
  571.       printf ("%2d%c %6d %4ld %8ld  ", Sdepth, ch, score, et / 100, NodeCnt);
  572.       ShowLine (bstline);
  573.       }
  574.     current_score = score;
  575.     current_depth = Sdepth;
  576.     for (i = 1; bstline[i] > 0; i++)
  577.       {
  578.       MV[i] = bstline[i];
  579.       }
  580.     MV[i] = 0;
  581. }
  582.  
  583. void
  584. SearchStartStuff (SHORT side)
  585. {
  586.     signal (SIGINT, TerminateSearch);
  587. #ifndef MSDOS
  588.     signal (SIGQUIT, TerminateSearch);
  589. #endif /* MSDOS */
  590.     if (flag.post)
  591.       {
  592.       fprintf (stderr, "\nMove# %d    Target= %ld    Clock: %ld\n",
  593.            move_number,
  594.            ResponseTime, TimeControl.clock[side]);
  595.       }
  596. }
  597.  
  598. void
  599. OutputMove (SHORT score)
  600. {
  601.     strcpy (suggest_move, mvstr[0]);
  602.     strcpy (suggest_move1, mvstr[1]);
  603.     strcpy (suggest_move2, mvstr[2]);
  604.     strcpy (suggest_move3, mvstr[3]);
  605.     print_score = current_score;
  606. }
  607.  
  608.  
  609. #ifdef HAVE_GETTIMEOFDAY
  610. #include <sys/time.h>
  611. void
  612. ElapsedTime (SHORT iop)
  613.  
  614.  
  615. /*
  616.  * Determine the time that has passed since the search was started. If the
  617.  * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
  618.  * to true which will terminate the search. iop = 0 calculate et bump ETnodes
  619.  * iop = 1 calculate et set timeout if time exceeded, calculate et
  620.  */
  621.  
  622. {
  623.     struct timeval tv;
  624.  
  625. #ifndef MSDOS
  626.     int nchar;
  627.     extern int errno;
  628.     int i;
  629.  
  630. #ifdef FIONREAD
  631.     if (i = ioctl ((int) 0, FIONREAD, &nchar))
  632.       {
  633.       perror ("FIONREAD");
  634.       fprintf (stderr,
  635.        "You probably have a non-ANSI <ioctl.h>; see README. %d %d %x\n",
  636.            i, errno, FIONREAD);
  637.       exit (1);
  638.       }
  639.     if (nchar)
  640.       {
  641.       if (!flag.timeout)
  642.           flag.back = true;
  643.       flag.bothsides = false;
  644.       }
  645. #endif /* FIONREAD */
  646. #else
  647.     if (kbhit ())
  648.       {
  649.       if (!flag.timeout)
  650.           flag.back = true;
  651.       flag.bothsides = false;
  652.       }
  653. #endif /* MSDOS */
  654.     gettimeofday (&tv, NULL);
  655.     et = (tv.tv_sec * 100 + (tv.tv_usec / 10000)) - time0;
  656.     ETnodes = NodeCnt + ZNODES;
  657.     if (et < 0)
  658.     et = 0;
  659.     if (iop == 1)
  660.       {
  661.       if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
  662.           flag.timeout = true;
  663.       ETnodes = NodeCnt + ZNODES;
  664.       gettimeofday (&tv, NULL);
  665.       time0 = tv.tv_sec * 100 + tv.tv_usec / 10000;
  666.       }
  667. }
  668.  
  669. #else
  670. void
  671. ElapsedTime (SHORT iop)
  672.  
  673.  
  674. /*
  675.  * Determine the time that has passed since the search was started. If the
  676.  * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
  677.  * to true which will terminate the search. iop = 0 calculate et bump ETnodes
  678.  * iop = 1 calculate et set timeout if time exceeded, calculate et
  679.  */
  680.  
  681. {
  682. #ifndef MSDOS
  683.     int nchar;
  684.     extern int errno;
  685.     int i;
  686.  
  687. #ifdef FIONREAD
  688.     if (i = ioctl ((int) 0, FIONREAD, &nchar))
  689.       {
  690.       perror ("FIONREAD");
  691.       fprintf (stderr,
  692.        "You probably have a non-ANSI <ioctl.h>; see README. %d %d %x\n",
  693.            i, errno, FIONREAD);
  694.       exit (1);
  695.       }
  696.     if (nchar)
  697.       {
  698.       if (!flag.timeout)
  699.           flag.back = true;
  700.       flag.bothsides = false;
  701.       }
  702. #endif /* FIONREAD */
  703. #else
  704.     if (kbhit ())
  705.       {
  706.       if (!flag.timeout)
  707.           flag.back = true;
  708.       flag.bothsides = false;
  709.       }
  710. #endif /* MSDOS */
  711.     et = (time ((long *) 0) - time0) * 100;
  712.     ETnodes = NodeCnt + ZNODES;
  713.     if (et < 0)
  714.     et = 0;
  715.     if (iop == 1)
  716.       {
  717.       if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
  718.           flag.timeout = true;
  719.       ETnodes = NodeCnt + ZNODES;
  720.       time0 = time ((long *) 0);
  721.       }
  722. }
  723.  
  724. #endif
  725. #ifdef notdef
  726. void
  727. ElapsedTime (SHORT iop)
  728.  
  729. /*
  730.  * Determine the time that has passed since the search was started. If the
  731.  * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
  732.  * to true which will terminate the search.
  733.  */
  734. {
  735.     et = (time ((long *) 0) - time0) * 100;
  736.     /* et = (clock ()/CLOCKS_PER_SEC - time0) * 100; */
  737.     if (et < 0)
  738.     et = 0;
  739.     ETnodes += ZNODES;
  740.     if (iop == 1)
  741.       {
  742.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  743.           flag.timeout = true;
  744.       time0 = time ((long *) 0);
  745.       /* time0 = clock () / CLOCKS_PER_SEC; */
  746.       ETnodes = NodeCnt + ZNODES;
  747.       }
  748. }
  749.  
  750. #endif
  751.  
  752. void
  753. SetTimeControl (void)
  754. {
  755.     if (TCflag)
  756.       {
  757.       TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
  758.       TimeControl.clock[white] = TimeControl.clock[black] = 6000L * TCminutes + 100L * TCseconds;
  759.       }
  760.     else
  761.       {
  762.       TimeControl.moves[white] = TimeControl.moves[black] = 0;
  763.       TimeControl.clock[white] = TimeControl.clock[black] = 0;
  764.       MaxResponseTime = 6000L * TCminutes + 100L * TCseconds;
  765.       }
  766.     et = 0;
  767.     ElapsedTime (1);
  768. }
  769.  
  770. void
  771. ClrScreen (void)
  772. {
  773. #ifndef CHESSTOOL
  774.     printz ("\n");
  775. #endif
  776. }
  777.  
  778. void
  779. UpdateDisplay (SHORT f, SHORT t, SHORT redraw, SHORT isspec)
  780. {
  781. #ifndef CHESSTOOL
  782.     SHORT r, c, l;
  783.  
  784.     if (!enable_update_display)
  785.     return;
  786.     if (redraw)
  787.       {
  788.       fprintf (fpout, "\n");
  789.       for (r = 7; r >= 0; r--)
  790.         {
  791.         for (c = 0; c <= 7; c++)
  792.           {
  793.               l = locn (r, c);
  794.               if (color[l] == neutral)
  795.               fprintf (fpout, " -");
  796.               else if (color[l] == white)
  797.               fprintf (fpout, " %c", qxx[board[l]]);
  798.               else
  799.               fprintf (fpout, " %c", pxx[board[l]]);
  800.           }
  801.         fprintf (fpout, "\n");
  802.         }
  803.       fprintf (fpout, "\n");
  804.       }
  805. #endif /* CHESSTOOL */
  806. #ifdef MSDOS
  807.     f++;
  808.     t++;
  809.     isspec++;            /* shut up the compiler */
  810. #endif /* MSDOS */
  811. }
  812.  
  813. void
  814. GetGame (void)
  815. {
  816. }
  817.  
  818. void
  819. SaveGame (void)
  820. {
  821. }
  822.  
  823. void
  824. ListGame (void)
  825. {
  826. }
  827.  
  828. void
  829. Undo (void)
  830.  
  831. /*
  832.  * Undo the most recent half-move.
  833.  */
  834.  
  835. {
  836.     SHORT f, t;
  837.  
  838.     f = GameList[GameCnt].gmove >> 8;
  839.     t = GameList[GameCnt].gmove & 0xFF;
  840.     if (board[t] == king && distance (t, f) > 1)
  841.     (void) castle (GameList[GameCnt].color, f, t, 2);
  842.     else
  843.       {
  844.       /* Check for promotion: */
  845.       if (GameList[GameCnt].flags & promote)
  846.         {
  847.         board[t] = pawn;
  848.         }
  849.       board[f] = board[t];
  850.       color[f] = color[t];
  851.       board[t] = GameList[GameCnt].piece;
  852.       color[t] = GameList[GameCnt].color;
  853.       if (color[t] != neutral)
  854.           Mvboard[t]--;
  855.       Mvboard[f]--;
  856.       }
  857.     if (GameList[GameCnt].flags & epmask)
  858.     EnPassant (otherside[color[f]], f, t, 2);
  859.     else
  860.     InitializeStats ();
  861.     epsquare = GameList[GameCnt].epssq;
  862.     if (TCflag && (TCmoves > 1))
  863.     ++TimeControl.moves[color[f]];
  864.     hashkey = GameList[GameCnt].hashkey;
  865.     hashbd = GameList[GameCnt].hashbd;
  866.     GameCnt--;
  867.     flag.mate = false;
  868.     Sdepth = 0;
  869.  
  870.     /*
  871.      * ShowSidetoMove (); UpdateDisplay (0, 0, 1, 0);
  872.      */
  873.     if (flag.regularstart)
  874.     Book = BOOKFAIL;
  875. }
  876.  
  877. #ifdef notdef
  878. void
  879. Undo (void)
  880.  
  881. /*
  882.  * Undo the most recent half-move.
  883.  */
  884.  
  885. {
  886.     SHORT f, t;
  887.  
  888.     f = GameList[GameCnt].gmove >> 8;
  889.     t = GameList[GameCnt].gmove & 0xFF;
  890.     if (board[t] == king && distance (t, f) > 1)
  891.     (void) castle (GameList[GameCnt].color, f, t, 2);
  892.     else
  893.       {
  894.       /* Check for promotion: */
  895.       if (GameList[GameCnt].flags & promote)
  896.         {
  897.         board[t] = pawn;
  898.         }
  899.       board[f] = board[t];
  900.       color[f] = color[t];
  901.       board[t] = GameList[GameCnt].piece;
  902.       color[t] = GameList[GameCnt].color;
  903.       if (color[t] != neutral)
  904.           Mvboard[t]--;
  905.       Mvboard[f]--;
  906.       }
  907.     if (GameList[GameCnt].flags & epmask)
  908.     EnPassant (color[t], f, t, 2);
  909.     if (TCflag)
  910.     ++TimeControl.moves[color[f]];
  911.     GameCnt--;
  912.     computer = otherside[computer];
  913.     opponent = otherside[opponent];
  914.     flag.mate = false;
  915.     Sdepth = 0;
  916.     InitializeStats ();
  917. }
  918.  
  919. #endif
  920. void
  921. ShowMessage (CHAR * s)
  922. {
  923.     fprintf (stderr, "%s\n", s);
  924. }
  925.  
  926. void
  927. ShowSidetoMove (void)
  928. {
  929. }
  930.  
  931. void
  932. PromptForMove (void)
  933. {
  934. #ifndef CHESSTOOL
  935.     printz ("\nYour move is? ");
  936. #endif /* CHESSTOOL */
  937. }
  938.  
  939.  
  940. void
  941. ShowCurrentMove (SHORT pnt, SHORT f, SHORT t)
  942. {
  943. #ifdef MSDOS
  944.     f++;
  945.     t++;
  946.     pnt++;            /* shut up the compiler */
  947. #endif /* MSDOS */
  948. }
  949.  
  950. void
  951. ChangeAlphaWindow (void)
  952. {
  953.     printz ("window: ");
  954. }
  955.  
  956. void
  957. ChangeBetaWindow (void)
  958. {
  959.     printz ("window: ");
  960. }
  961.  
  962. void
  963. GiveHint (void)
  964. {
  965.     algbr ((SHORT) (hint >> 8), (SHORT) (hint & 0xFF), false);
  966.     fprintf (stderr, "Hint: %s\n", mvstr[0]);
  967. }
  968.  
  969. void
  970. SelectLevel (CHAR * sx)
  971. {
  972. }
  973.  
  974. void
  975. ChangeSearchDepth (void)
  976. {
  977.     printz ("depth= ");
  978.     scanz ("%d", &MaxSearchDepth);
  979. }
  980.  
  981. void
  982. SetContempt (void)
  983. {
  984.     printz ("contempt= ");
  985.     scanz ("%hd", &contempt);
  986. }
  987.  
  988. void
  989. ChangeXwindow (void)
  990. {
  991.     printz ("xwndw= ");
  992.     scanz ("%hd", &xwndw);
  993. }
  994.  
  995. void
  996. TestSpeed (void (*f) (SHORT side, SHORT ply))
  997. {
  998.     SHORT i;
  999.     long cnt, rate, t1, t2;
  1000.  
  1001.     t1 = time (0);
  1002.     for (i = 0; i < 10000; i++)
  1003.       {
  1004.       f (opponent, 2);
  1005.       }
  1006.     t2 = time (0);
  1007.     cnt = 10000L * (TrPnt[3] - TrPnt[2]);
  1008.     rate = cnt / (t2 - t1);
  1009.     printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);
  1010. }
  1011.  
  1012. CHAR cbuf[256];
  1013. CHAR sdepth[128];
  1014. int sdindex;
  1015. SHORT GNCmode;
  1016. CHAR *GetNextPtr = (CHAR *) NULL;
  1017.  
  1018. signed char GetNextChar ()
  1019. {
  1020.     GNCmode = false;
  1021.     while (true)
  1022.       {
  1023.       if (GetNextPtr == NULL)
  1024.         {
  1025.         if (fgets (cbuf, sizeof (cbuf), fpin) != NULL)
  1026.           {
  1027.               GetNextPtr = cbuf;
  1028.           }
  1029.         else
  1030.             return -1;
  1031.         }
  1032.       else
  1033.           GetNextPtr++;
  1034.       if (*GetNextPtr == '\n' || *GetNextPtr == '\0')
  1035.         {
  1036.         GetNextPtr = NULL;
  1037.         return ' ';
  1038.         }
  1039.       if (GNCmode)
  1040.           if (*GetNextPtr == '}')
  1041.         {
  1042.             GNCmode = false;
  1043.             continue;
  1044.         }
  1045.           else
  1046.           continue;
  1047.       if (*GetNextPtr == '{')
  1048.         {
  1049.         GNCmode = true;
  1050.         continue;
  1051.         }
  1052.       return (*GetNextPtr);
  1053.  
  1054.       }
  1055. }
  1056. int lastws = true;
  1057. static signed char GNUANc;
  1058. int
  1059. GetNextMove (CHAR * buffer)
  1060. {
  1061.     CHAR *p, *q;
  1062.  
  1063.     sdw = sdb = 0;
  1064.     black_actual_move[0] = '\0';
  1065.     white_actual_move[0] = '\0';
  1066.     if (InFileType == PGN)
  1067.       {
  1068.       lastws = true;
  1069.       while (!isalpha (GNUANc))
  1070.         {
  1071.         if (GNUANc == '0' && lastws)
  1072.             break;
  1073.         if (GNUANc == ' ' || GNUANc == '.')
  1074.             lastws = true;
  1075.         else
  1076.             lastws = false;
  1077.         GNUANc = GetNextChar ();
  1078.         if (GNUANc == -1 && GetNextPtr == NULL)
  1079.             return -1;
  1080.         }
  1081.       q = white_actual_move;
  1082.       while (GNUANc != ' ' && GNUANc != -1)
  1083.         {
  1084.         if (GNUANc != 'x' && GNUANc != '+')
  1085.             *q++ = GNUANc;
  1086.         GNUANc = GetNextChar ();
  1087.         }
  1088.       *q = '\0';
  1089.       lastws = true;
  1090.       while (!isalpha (GNUANc))
  1091.         {
  1092.         if (GNUANc == '0' && lastws)
  1093.             break;
  1094.         if (GNUANc == ' ')
  1095.             lastws = true;
  1096.         else
  1097.             lastws = false;
  1098.         GNUANc = GetNextChar ();
  1099.         if (GetNextPtr == NULL)
  1100.             return 1;
  1101.         }
  1102.       q = black_actual_move;
  1103.       while (GNUANc != ' ' && GNUANc != -1)
  1104.         {
  1105.         if (GNUANc != 'x' && GNUANc != '+')
  1106.             *q++ = GNUANc;
  1107.         GNUANc = GetNextChar ();
  1108.         }
  1109.       *q = '\0';
  1110.       return 2;
  1111.  
  1112.       }
  1113.     if (fgets (cbuf, sizeof (cbuf), fpin) != NULL)
  1114.       {
  1115.       p = cbuf;
  1116.       for (; *p; p++)
  1117.         {
  1118.         if (isalpha (*p))
  1119.           {
  1120.               q = white_actual_move;
  1121.               while (!isspace (*p))
  1122.               *q++ = *p++;
  1123.               *q = '\0';
  1124.               if (strcmp (white_actual_move, "Book") == 0)
  1125.               continue;
  1126.               else
  1127.               break;
  1128.               break;
  1129.           }
  1130.         }
  1131.       if (*p == '\0' && white_actual_move[0] == '\0')
  1132.           return 0;
  1133.       if (InFileType == GNUCHESS)
  1134.         {
  1135.         if (samedepth)
  1136.           {
  1137.               sdindex = 0;
  1138.               while (*p == ' ' || *p == '\n')
  1139.               p++;
  1140.               while (*p != ' ' && *p != '\0')
  1141.               p++;
  1142.               while (*p == ' ' || *p == '\n')
  1143.               p++;
  1144.               while (*p != ' ' && *p != '\n')
  1145.               sdepth[sdindex++] = *p++;
  1146.               sdepth[sdindex] = '\0';
  1147.               if (strcmp (sdepth, "Book") == 0)
  1148.             {
  1149.                 sdw = -99;
  1150.                 for (; *p != ' '; p++);
  1151.             }
  1152.               else
  1153.               sdw = atoi (sdepth);
  1154.           }
  1155.         }
  1156.       for (; *p; p++)
  1157.         {
  1158.         if (isalpha (*p))
  1159.           {
  1160.               q = black_actual_move;
  1161.               while (!isspace (*p))
  1162.               *q++ = *p++;
  1163.               *q = '\0';
  1164.               if (strcmp (black_actual_move, "Book") == 0)
  1165.               continue;
  1166.               else
  1167.               break;
  1168.           }
  1169.         }
  1170.       if (*p == '\0' && black_actual_move[0] == '\0')
  1171.           return 1;
  1172.       if (InFileType == GNUCHESS)
  1173.         {
  1174.         if (samedepth)
  1175.           {
  1176.               sdindex = 0;
  1177.               while (*p == ' ' || *p == '\n')
  1178.               p++;
  1179.               while (*p != ' ' && *p != '\0')
  1180.               p++;
  1181.               while (*p == ' ' || *p == '\n')
  1182.               p++;
  1183.               while (*p != ' ' && *p != '\n')
  1184.               sdepth[sdindex++] = *p++;
  1185.               sdepth[sdindex] = '\0';
  1186.               if (strcmp (sdepth, "Book") == 0)
  1187.             {
  1188.                 sdb = -99;
  1189.                 for (; *p != ' '; p++);
  1190.             }
  1191.               else
  1192.               sdb = atoi (sdepth);
  1193.           }
  1194.         }
  1195.       return 2;
  1196.       }
  1197.     else            /* EOF */
  1198.     return -1;
  1199.  
  1200. }
  1201. UTSHORT mv;
  1202. UTSHORT GNUANmv;
  1203.  
  1204. int DoIt (SHORT computer, CHAR * smove, SHORT inbook, CHAR * s)
  1205. {
  1206.     SHORT dok, i;
  1207.  
  1208.     dok = VerifyMove (smove, 0, &mv);
  1209.     if (!dok)
  1210.       {
  1211.       fprintf (fpout, "\nBad move.  %s  Board position is: \n", s);
  1212.       UpdateDisplay (0, 0, 1, 0);
  1213.       flag.quit = 1;
  1214.       return false;
  1215.       }
  1216.     if (inbook)
  1217.       {
  1218.       if (computer == black)
  1219.           fprintf (fpout, "            %-9s   -     -    book\n", smove);
  1220.       else
  1221.           fprintf (fpout, "%3d   %-9s         -     -    book\n", move_number, smove);
  1222.  
  1223.       fflush (fpout);
  1224.       Sdepth = 0;
  1225.       ft = 0;
  1226.       same_moves[computer]++;
  1227.       }
  1228.     else
  1229.       {
  1230.       CHAR x[8];
  1231.  
  1232.       strcpy (x, smove);
  1233.       if (strcmp (smove, suggest_move) == 0
  1234.           || strcmp (smove, suggest_move1) == 0
  1235.           || strcmp (smove, suggest_move2) == 0
  1236.           || strcmp (smove, suggest_move3) == 0)
  1237.         {
  1238.         same_moves[computer]++;
  1239.         }
  1240.       else
  1241.           strcat (x, "*");
  1242.       if (computer == white)
  1243.         {
  1244.         if (sdw == -99)
  1245.             fprintf (fpout, "%3d   %-9s      %5d   Book ", move_number, x, print_score);
  1246.         else
  1247.             fprintf (fpout, "%3d   %-9s      %5d%5d   ", move_number, x, print_score, current_depth);
  1248.         }
  1249.       else
  1250.         {
  1251.         if (sdb == -99)
  1252.             fprintf (fpout, "            %-9s%5d  Book  ", x, print_score);
  1253.         else
  1254.             fprintf (fpout, "            %-9s%5d%5d   ", x, print_score, current_depth);
  1255.         }
  1256.       for (i = 1; MV[i] > 0; i++)
  1257.         {
  1258. /*        if(i == 1)fprintf (fpout, "%5s ", suggest_move1); */
  1259. /*        else*/ {algbr ((SHORT) (MV[i] >> 8), (SHORT) (MV[i] & 0xFF), false);
  1260.         fprintf (fpout, "%5s ", mvstr[0]);}
  1261.         }
  1262. #ifdef notdef
  1263.       GNUANlist (MV);
  1264. #endif
  1265.       fprintf (fpout, "\n");
  1266.       fflush (fpout);
  1267.       Sdepth = 0;
  1268.       ft = 0;
  1269.       }
  1270.     return true;
  1271. }
  1272.  
  1273. void
  1274. GNUANvarit ()
  1275. {
  1276.     memcpy (&GNUANsave[GNUANsavedepth].board, board, sizeof (board));
  1277.     memcpy (&GNUANsave[GNUANsavedepth].color, color, sizeof (color));
  1278.     memcpy (&GNUANsave[GNUANsavedepth].mvboard, Mvboard, sizeof (Mvboard));
  1279.     GNUANsave[GNUANsavedepth].currmove = GNUANcurrmove;
  1280.     GNUANsave[GNUANsavedepth].basemove = GNUANbasemove;
  1281.     GNUANsave[GNUANsavedepth].movecnt = GNUANmovecnt;
  1282.     GNUANcurrmove = GNUANmovecnt - 1;
  1283.     GNUANbasemove = GNUANmovecnt;
  1284.     GNUANmovecnt = 0;
  1285.     GNUANsave[GNUANsavedepth].moveno = move_number;
  1286.     GNUANsavedepth++;
  1287. }
  1288. void
  1289. GNUANravit ()
  1290. {
  1291.     GNUANsavedepth--;
  1292.     memcpy (board, &GNUANsave[GNUANsavedepth].board, sizeof (board));
  1293.     memcpy (color, &GNUANsave[GNUANsavedepth].color, sizeof (color));
  1294.     memcpy (Mvboard, &GNUANsave[GNUANsavedepth].mvboard, sizeof (Mvboard));
  1295.     GNUANcurrmove = GNUANsave[GNUANsavedepth].currmove;
  1296.     GNUANbasemove = GNUANsave[GNUANsavedepth].basemove;
  1297.     GNUANmovecnt = GNUANsave[GNUANsavedepth].movecnt;
  1298.     move_number = GNUANsave[GNUANsavedepth].moveno;
  1299. }
  1300.  
  1301. int Undid = false;
  1302.  
  1303. void
  1304. InputCommand (void)
  1305.  
  1306. /*
  1307.  * Open the file of moves to analyse.  Go through the file move by move and
  1308.  * do the following for each move.  See what gnuchess would have done in that
  1309.  * position.  Record the move it would have made along with the score it
  1310.  * would have given and the search depth.  Take back its move. Force the move
  1311.  * that was actually made.  Keep track of statistics such as how many moves
  1312.  * agreed.
  1313.  */
  1314.  
  1315. {
  1316.     SHORT ok, inbook;
  1317.     CHAR s[80];
  1318.     int search_depth;
  1319.  
  1320. #if !defined BACKGROUND_ANALYSIS
  1321.     int max_minutes;
  1322.     int max_seconds;
  1323.     CHAR inbuf[256];
  1324. #else
  1325.     CHAR outfilename[255];
  1326.     CHAR progfilename[255];
  1327. #endif
  1328.     CHAR infilename[255];
  1329.     long start_time, end_time, elapsed_time;
  1330.     float move_percent[2];
  1331.     CHAR GNUANinbuf1[128];
  1332.     CHAR *p, *q;
  1333.     int mr;
  1334.  
  1335.     /* Initialize necessary variables. */
  1336.  
  1337.     flag.quit = false;
  1338.     flag.beep = false;
  1339.     flag.post = true;
  1340.     enable_update_display = 1;
  1341.     ft = 0;
  1342.     Book = false;
  1343.     total_moves[0] = total_moves[1] = 0;
  1344.     same_moves[0] = same_moves[0] = 0;
  1345.  
  1346. #ifdef BACKGROUND_ANALYSIS
  1347.  
  1348.     /*
  1349.      * Set the in files to standard ones for analysis if background
  1350.      * processing selected.
  1351.      */
  1352.  
  1353.     strcpy (infilename, IN_FILE);
  1354.     strcpy (outfilename, OUT_FILE);
  1355.     strcpy (progfilename, PROG_FILE);
  1356.     fpout = fopen (outfilename, "w");
  1357.     if (fpout == NULL)
  1358.       {
  1359.       fprintf (fpout, "This file does not exist : %s\n", outfilename);
  1360.       flag.quit = 1;
  1361.       return;
  1362.       }
  1363.     MaxSearchDepth = search_depth = MAX_DEPTH;
  1364.     TCminutes = MAX_MINUTE;
  1365.     TCseconds = MAX_SECOND;
  1366.  
  1367. #else
  1368.  
  1369.     /* Request information on where the file is and the depth an time. */
  1370.  
  1371.     fpout = stderr;
  1372.     fprintf (fpout, "Input the file with the algebraic moves of the game.\n");
  1373.     fflush (fpout);
  1374.     gets (infilename);
  1375.     fprintf (fpout, "\n");
  1376.     do
  1377.       {
  1378.       fprintf (fpout, "Input the search depth you want to use.  (1 to 29)(- for depth from file)\n");
  1379.       gets (inbuf);
  1380.       search_depth = atoi (inbuf);
  1381.       if (search_depth < 0)
  1382.         {
  1383.         samedepth = true;
  1384.         search_depth = -search_depth;
  1385.         }
  1386.       }
  1387.     while (search_depth < 1 || search_depth > 29);
  1388.     MaxSearchDepth = search_depth;
  1389.  
  1390.     fprintf (fpout, "\n");
  1391.     max_minutes = max_seconds = 0;
  1392.     do
  1393.       {
  1394.       fprintf (fpout, "Input the maximum number of minutes per move you want to use.\n");
  1395.       gets (inbuf);
  1396.       max_minutes = atoi (inbuf);
  1397.       if (max_minutes < 0)
  1398.         {
  1399.         max_seconds = -max_minutes;
  1400.         max_minutes = 0;
  1401.         }
  1402.       }
  1403.     while ((max_minutes + max_seconds) < 1);
  1404.     fprintf (fpout, "Post the search results(y/n).\n");
  1405.     gets (inbuf);
  1406.     if (inbuf[0] == 'y')
  1407.     flag.post = true;
  1408.     else
  1409.     flag.post = false;
  1410.     printf ("\nYou will search to %d half moves\n", search_depth);
  1411.     printf ("\nWith no search taking more than %d:%02d minutes\n", max_minutes, max_seconds);
  1412.     TCminutes = max_minutes;
  1413.     TCseconds = max_seconds;
  1414.  
  1415.     fprintf (fpout, "\n\n");
  1416.  
  1417. #endif
  1418.  
  1419.     fpin = fopen (infilename, "r");
  1420.     if (fpin == NULL)
  1421.       {
  1422.       fprintf (fpout, "This file does not exist : %s\n", infilename);
  1423.       flag.quit = 1;
  1424.       return;
  1425.       }
  1426.     /* lets find out about this file */
  1427.     fgets (InBuf, 256, fpin);
  1428.     InFileType = OTHER;
  1429.     if (!strncmp (InBuf, "xboard", 6) || !strncmp (InBuf, "# xboard", 8))
  1430.       {
  1431.       InFileType = XBOARD;
  1432.       fgets (InBuf, 256, fpin);
  1433.       fgets (InBuf, 256, fpin);
  1434.       }
  1435.     else if (!strncmp (InBuf, "gnuchess", 6))
  1436.       {
  1437.       InFileType = GNUCHESS;
  1438.       fgets (InBuf, 256, fpin);
  1439.       }
  1440.     else if (InBuf[0] == '[')
  1441.       {
  1442.       InFileType = PGN;
  1443.       while (InBuf[0] == '[')
  1444.         {
  1445.         fprintf (fpout, "%s", InBuf);
  1446.         fgets (InBuf, 256, fpin);
  1447.         }
  1448.       fprintf (fpout, "\n");
  1449.       }
  1450.     else
  1451.     rewind (fpin);
  1452.     TCmoves = 1;
  1453.     TCflag = (TCmoves > 1);
  1454.     /* flag.onemove = true; */
  1455.     OperatorTime = 0;
  1456.     SetTimeControl ();
  1457.  
  1458.  
  1459.     fprintf (fpout, "Move White Black      Score Depth     Best Line\n");
  1460.     fprintf (fpout, "------------------------------------------------------------------\n");
  1461.  
  1462. #ifdef BACKGROUND_ANALYSIS
  1463.  
  1464.     /*
  1465.      * Update progress in the progress file if this is running in the
  1466.      * background.
  1467.      */
  1468.  
  1469.     fpprog = fopen (progfilename, "w");
  1470.     fprintf (fpprog, "Done with move #%d.\n", move_number - 1);
  1471.     fclose (fpprog);
  1472.  
  1473. #endif
  1474.     GNUANmovecnt = 0;
  1475.     GNUANbasemove = 0;
  1476.     while ((mr = GetNextMove (s)) > 0)
  1477.       {
  1478.       strcpy (GNUANmove[GNUANmovecnt], white_actual_move);
  1479.       GNUANsd[GNUANmovecnt] = (sdw == -99) ? search_depth : (sdw) ? sdw : search_depth;
  1480.       GNUANmovecnt++;
  1481.         if (mr == 1) break;
  1482.       strcpy (GNUANmove[GNUANmovecnt], black_actual_move);
  1483.       GNUANsd[GNUANmovecnt] = (sdb == -99) ? search_depth : (sdb) ? sdb : search_depth;
  1484.       GNUANmovecnt++;
  1485.       if (!strcmp (white_actual_move, "Black") || !strcmp (white_actual_move, "White") || !strcmp (white_actual_move, "draw"))
  1486.           break;
  1487.       }
  1488.     printf ("Got %d moves\n", GNUANmovecnt);
  1489.  
  1490.     /* all the moves are stored now start */
  1491.     opponent = black;
  1492.     computer = white;
  1493.     GNUANinput = file;
  1494.     GNUANnext = false;
  1495.     GNUANnextstop = GNUANsavedepth = GNUANcurrmove = 0;
  1496.     time (&start_time);
  1497.     Undid = false;
  1498.     while (GNUANcurrmove < (GNUANbasemove + GNUANmovecnt))
  1499.       {
  1500.  
  1501. #ifdef IGNUAN
  1502. /************************************************************************/
  1503.       /* gnuan interactive                                */
  1504. /************************************************************************/
  1505.  
  1506.       /*
  1507.        * Commands: var - initiate a variation - save current another - find
  1508.        * next best move for this position top - always look at the top n
  1509.        * moves comment - copy to output rav - return from variation go get
  1510.        * next move from input
  1511.        */
  1512. /************************************************************************/
  1513. #endif
  1514.       if (GNUANdepth)
  1515.           MaxSearchDepth = GNUANdepth;
  1516.       else
  1517.         {
  1518.         if (GNUANinput == file)
  1519.             MaxSearchDepth = GNUANsd[GNUANcurrmove];
  1520.         else
  1521.             MaxSearchDepth = 4;
  1522.         }
  1523.       if (GNUANnext)
  1524.         {
  1525.         GNUANnext = false;
  1526.         inbook = false;
  1527.         }
  1528.       else
  1529.         {
  1530.         VMoveList (computer, 1);
  1531.         inbook = GOpeningBook (&GNUANhint, computer, GNUANmove[GNUANcurrmove]);
  1532.         }
  1533.  
  1534.       if (!inbook)
  1535.         {
  1536.         flag.force = 0;
  1537.         SelectMove (computer, 1);
  1538.         Undo ();
  1539.         SetTimeControl ();
  1540.         flag.force = 1;
  1541.         }
  1542.       if (GNUANinput == file)
  1543.           ok = DoIt (computer, GNUANmove[GNUANcurrmove], inbook, s);
  1544.       else
  1545.           ok = DoIt (computer, GNUANinbuf, inbook, s);
  1546.       if (!ok)
  1547.         {
  1548.         if (GNUANinput == keyboard)
  1549.             GNUANmovecnt--;
  1550.         GNUANcurrmove--;
  1551.         }
  1552. #ifdef BACKGROUND_ANALYSIS
  1553.  
  1554.       /*
  1555.        * Update progress in the progress file if this is running in the
  1556.        * background.
  1557.        */
  1558.  
  1559.       fpprog = fopen (progfilename, "w");
  1560.       fprintf (fpprog, "Done with move #%d.\n", move_number - 1);
  1561.       fclose (fpprog);
  1562. #else
  1563.  
  1564.       /*
  1565.        * fprintf(stderr, "Done with move #%d.\n", move_number-1);
  1566.        */
  1567.  
  1568. #endif
  1569. #ifdef IGNUAN
  1570.       /* we have done the move now any commands */
  1571.       if(GNUANtopLim){
  1572.         if(GNUANtop < GNUANtopLim){
  1573.              GNUANadjlist[GNUANtop++] = GNUANmv;
  1574.                           GNUANnext = true;
  1575.                           Undo ();
  1576.                           Undid = true;
  1577.             }
  1578.         else GNUANtop = 0;
  1579.         }
  1580.       if (GNUANcurrmove >= GNUANnextstop) GNUANnextstop = 0;
  1581.       if (GNUANnextstop == 0 && (GNUANtopLim == 0 || GNUANtop == 0))
  1582.           while (true)
  1583.         {
  1584.             printf (">");
  1585.             gets (GNUANinbuf1);
  1586.             p = GNUANinbuf1;
  1587.             q = GNUANinbuf;
  1588.             while (true)
  1589.               {
  1590.               while (true)
  1591.                 {
  1592.                 if (*p == ' ')
  1593.                   {
  1594.                       p++;
  1595.                       continue;
  1596.                   }
  1597.                 else
  1598.                     break;
  1599.                 }
  1600.               while (true)
  1601.                 {
  1602.                 if (*p != ' ')
  1603.                   {
  1604.                       if (*p == '\0')
  1605.                     {
  1606.                         break;
  1607.                     }
  1608.                       *q++ = *p++;
  1609.                       continue;
  1610.                   }
  1611.                 else
  1612.                     break;
  1613.                 }
  1614.               if (*p == '\0')
  1615.                   break;
  1616.               else
  1617.                   *q++ = ' ';
  1618.               }
  1619.             *q = '\0';
  1620.             if (strcmp ("var", GNUANinbuf) == 0)
  1621.               {
  1622.               GNUANvarit ();
  1623.               GNUANinput = keyboard;
  1624.               }
  1625.             else if (strcmp ("rav", GNUANinbuf) == 0)
  1626.               {
  1627.               if (GNUANsavedepth == 0)
  1628.                 {
  1629.                 printf ("Error not in Var\n");
  1630.                 continue;
  1631.                 }
  1632.               GNUANravit ();
  1633.               InitializeStats ();
  1634.               GNUANinput = (GNUANsavedepth ? keyboard : file);
  1635.               }
  1636.             else if (strcmp ("next", GNUANinbuf) == 0 || strcmp ("n", GNUANinbuf) == 0)
  1637.               {
  1638.               GNUANadjlist[GNUANtop++] = GNUANmv;
  1639.               GNUANnext = true;
  1640.               Undo ();
  1641.               Undid = true;
  1642.               break;
  1643.               }
  1644.             else if ((strncmp ("depth", GNUANinbuf, 5) == 0))
  1645.               {
  1646.               int i = strtol (&GNUANinbuf[5], NULL, 10);
  1647.               if (i > 0)
  1648.                   GNUANdepth = i;
  1649.               else
  1650.                 {
  1651.                 printf ("Illegal depth %d\n", i);
  1652.                 continue;
  1653.                 }
  1654.               }
  1655.             else if (strcmp ("wn", GNUANinbuf) == 0)
  1656.               {
  1657.               GNUANtop = 0;
  1658.               }
  1659.             else if (strncmp ("d", GNUANinbuf, 2) == 0)
  1660.               {
  1661.               int i = strtol (&GNUANinbuf[2], NULL, 10);
  1662.               if (i > 0)
  1663.                   GNUANdepth = i;
  1664.               else
  1665.                 {
  1666.                 printf ("Illegal depth %d\n", i);
  1667.                 continue;
  1668.                 }
  1669.               }
  1670.             else if (strncmp ("top", GNUANinbuf, 3) == 0)
  1671.               {
  1672.               int i = strtol (&GNUANinbuf[4], NULL, 10);
  1673.               if (i > 1 && i < 6)
  1674.                   GNUANtopLim = i-1;
  1675.               else
  1676.                   printf ("Illegal range for top %d\n", i);
  1677.               }
  1678.             else if (strncmp ("t", GNUANinbuf, 2) == 0)
  1679.               {
  1680.               int i = strtol (&GNUANinbuf[2], NULL, 10);
  1681.               if (i > 0 && i < 99)
  1682.                   GNUANtop = i;
  1683.               else
  1684.                   printf ("Illegal range for top %d\n", i);
  1685.               }
  1686.             else if (strcmp ("bd", GNUANinbuf) == 0)
  1687.               {
  1688.               UpdateDisplay (0, 0, 1, 0);
  1689.               }
  1690.             else if (strcmp ("quit", GNUANinbuf) == 0)
  1691.               {
  1692.               exit (1);
  1693.               }
  1694.             else if (strcmp ("go", GNUANinbuf) == 0 || strcmp ("g", GNUANinbuf) == 0)
  1695.               {
  1696.               if (!GNUANsavedepth)
  1697.                   break;
  1698.               else
  1699.                   printf ("In variation need move or rav\n");
  1700.               }
  1701.             else if (isdigit (GNUANinbuf[0]))
  1702.               {
  1703.               /* means go to move nn */
  1704.               GNUANnextstop = 2 * (strtol (GNUANinbuf, &p, 10) - 1) - 1;
  1705.               if (GNUANnextstop <= GNUANcurrmove)
  1706.                 {
  1707.                 printf ("already past that move\n");
  1708.                 GNUANnextstop = 0;
  1709.                 continue;
  1710.                 }
  1711.               break;
  1712.               }
  1713.             else
  1714.               {        /* none of above must be a move if in a var */
  1715.               if (!GNUANsavedepth)
  1716.                 {
  1717.                 printf ("Illegal input:must be in var to specify move\n");
  1718.                 continue;
  1719.                 }
  1720.               if (strlen (GNUANinbuf) < 2)
  1721.                 {
  1722.                 printf ("Illegal input:%s\n", GNUANinbuf);
  1723.                 continue;
  1724.                 }
  1725.               else
  1726.                 {
  1727.                 strcpy (GNUANmove[GNUANbasemove + GNUANmovecnt], GNUANinbuf);
  1728.                 GNUANmovecnt++;
  1729.                 GNUANinput = keyboard;
  1730.                 break;
  1731.                 }
  1732.               }
  1733.  
  1734.         }
  1735. #endif
  1736.       if (!Undid)
  1737.         {
  1738.         computer ^= 1;
  1739.         opponent ^= 1;
  1740.         GNUANcurrmove++;
  1741.             if (computer == white) move_number++;
  1742.         }
  1743.       Undid = false;
  1744.       }
  1745.  
  1746.     move_percent[white] = ((float) same_moves[white]) * 200 / (float) (GNUANmovecnt + (GNUANmovecnt % 2 ? 1 : 0));
  1747.     move_percent[black] = ((float) same_moves[black]) * 200 / (float) (GNUANmovecnt + (GNUANmovecnt % 2 ? 1 : 0));
  1748.     fprintf (fpout, "\n           White's percentage was %5.2f%%.     Black's percentage was %5.2f%%.\n", move_percent[white], move_percent[black]);
  1749.     time (&end_time);
  1750.     elapsed_time = end_time - start_time;
  1751.     fprintf (fpout, "\n           Elapsed time was %ld seconds.\n", elapsed_time);
  1752.     fclose (fpin);
  1753.     fclose (fpout);
  1754.     exit (0);
  1755. }
  1756.  
  1757. void
  1758. Ldisplay1 ()
  1759. {
  1760. };
  1761. void
  1762. Ldisplay2 ()
  1763. {
  1764. };
  1765. void
  1766. Ldisplay ()
  1767. {
  1768. };
  1769. void
  1770. Ldisplay3 ()
  1771. {
  1772. };
  1773. void
  1774. Ldisplay4 ()
  1775. {
  1776. };
  1777. int ecomove;
  1778.