#include "chess.h"
 
#include "data.h"
 
/* last modified 02/26/14 */
 
/*
 
 *******************************************************************************
 
 *                                                                             *
 
 *   EVTest() is used to test the program against a suite of test positions to *
 
 *   measure its performance on a particular machine, or to evaluate its skill *
 
 *   after modifying it in some way.                                           *
 
 *                                                                             *
 
 *   The test is initiated by using the "evtest <filename>" command to read in *
 
 *   the suite of problems from file <filename>.  The format of this file is   *
 
 *   as follows:                                                               *
 
 *                                                                             *
 
 *   <forsythe-string>  This sets the board position using the usual Forsythe  *
 
 *   notation (see module SetBoard() for a full explanation explanation of the *
 
 *   syntax).                                                                  *
 
 *                                                                             *
 
 *   After reading this position, the program then calls Evaluate() to produce *
 
 *   a positional evaluation, along with any debug output from Evaluate(), and *
 
 *   then goes on to the next position.                                        *
 
 *                                                                             *
 
 *   A common use (with code included below) is to take a position, and then   *
 
 *   "flip" it (reverse the board rank by rank changing the color of each      *
 
 *   piece as this is done, giving us two positions.  We then take each of     *
 
 *   these and mirror them, which reverses them file by file, which now gives  *
 
 *   four positions in total.  We run these thru Evaluate() to make sure that  *
 
 *   all produce exactly the same score, except for the color change for the   *
 
 *   two that changed the piece colors.  This is used to make certain that the *
 
 *   evaluation is not asymmetric with respect to the colors, or to the side   *
 
 *   of the board, which catches errors that are difficult to spot otherwise.  *
 
 *                                                                             *
 
 *******************************************************************************
 
 */
 
void EVTest(char *filename) {
 
  FILE *test_input;
 
  char *eof;
 
  char buff[4096];
 
  TREE *const tree = block[0];
 
 
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  Read in the position                                    *
 
 *                                                          *
 
 ************************************************************
 
 */
 
  if (!(test_input 
= fopen(filename
, "r"))) {  
    printf("file %s does not exist.\n", filename
);  
    return;
 
  }
 
  while (1) {
 
    eof 
= fgets(buffer
, 4096, test_input
); 
    if (eof) {
 
      char *delim;
 
 
 
      if (delim)
 
        *delim = 0;
 
      if (delim)
 
        *delim = ' ';
 
    } else
 
      break;
 
    strcpy_s(buff, sizeof (buff), buffer); // Pierre-Marie Baty -- use safe version
 
    nargs = ReadParse(buffer, args, " ;");
 
      break;
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  Now for the asymmetry tests.  We use the built-in       *
 
 *  commands "flip" and "flop" to create the four           *
 
 *  positions, and call Evaluate() for each.                *
 
 *                                                          *
 
 ************************************************************
 
 */
 
    else {
 
      int s1, s2, s3, s4, id;
 
 
 
      for (id = 2; id < nargs; id++)
 
          break;
 
      if (id >= nargs)
 
        id = 0;
 
      SetBoard(tree, nargs, args, 0);
 
      Castle(0, white) = 0;
 
      Castle(1, white) = 0;
 
      Castle(0, black) = 0;
 
      Castle(1, black) = 0;
 
      root_wtm = game_wtm;
 
      tree->pawn_score.key = 0;
 
      s1 = Evaluate(tree, 0, game_wtm, -99999, 99999);
 
      strcpy_s(buffer, sizeof (buffer), "flop"); // Pierre-Marie Baty -- use safe version
 
      (void) Option(tree);
 
      tree->pawn_score.key = 0;
 
      s2 = Evaluate(tree, 0, game_wtm, -99999, 99999);
 
      strcpy_s(buffer, sizeof (buffer), "flip"); // Pierre-Marie Baty -- use safe version
 
      (void) Option(tree);
 
      tree->pawn_score.key = 0;
 
      s3 = Evaluate(tree, 0, game_wtm, -99999, 99999);
 
      strcpy_s(buffer, sizeof (buffer), "flop"); // Pierre-Marie Baty -- use safe version
 
      (void) Option(tree);
 
      tree->pawn_score.key = 0;
 
      s4 = Evaluate(tree, 0, game_wtm, -99999, 99999);
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  If the evaluations (with sign corrected if piece color  *
 
 *  was changed) are different, we display the four values  *
 
 *  and then display the original board position so that we *
 
 *  can debug the cause of the asymmetry.                   *
 
 *                                                          *
 
 ************************************************************
 
 */
 
      if (s1 != s2 || s1 != s3 || s1 != s4 || s2 != s3 || s2 != s4 ||
 
          s3 != s4) {
 
        strcpy_s(buffer, sizeof (buffer), "flip"); // Pierre-Marie Baty -- use safe version
 
        (void) Option(tree);
 
        DisplayChessBoard(stdout, tree->position);
 
        if (id)
 
          Print(4095, "id=%s  ", args[id + 1]);
 
        Print(4095, "wtm=%d  score=%d  %d (flop)  %d (flip)  %d (flop)\n",
 
            game_wtm, s1, s2, s3, s4);
 
      }
 
    }
 
  }
 
  input_stream = stdin;
 
}