Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.     Protector -- a UCI chess engine
  3.  
  4.     Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com)
  5.  
  6.     This program is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation, either version 3 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. */
  20.  
  21. #include <assert.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "test.h"
  26. #include "io.h"
  27. #include "pgn.h"
  28. #include "coordination.h"
  29. #include "evaluation.h"
  30.  
  31. extern bool resetSharedHashtable;
  32.  
  33. static void handleSearchEvent(int eventId, void *var)
  34. {
  35.    Variation *variation = (Variation *) var;
  36.    long time;
  37.    char *pvMoves;
  38.  
  39.    switch (eventId)
  40.    {
  41.    case SEARCHEVENT_SEARCH_FINISHED:
  42.       time = variation->finishTimeProcess - variation->startTimeProcess;
  43.  
  44.       logReport("%lld nodes in %ld msec\n", getNodeCount(), time);
  45.  
  46.       if (time > 1000)
  47.       {
  48.          logReport("%ld knps\n", getNodeCount() / max(1, time));
  49.       }
  50.  
  51.       break;
  52.  
  53.    case SEARCHEVENT_PLY_FINISHED:
  54.    case SEARCHEVENT_NEW_PV:
  55.       pvMoves = getPrincipalVariation(var);
  56.       dumpPv(variation->iteration,
  57.              (getTimestamp() - variation->startTime), pvMoves,
  58.              variation->pv[0].score, variation->nodes,
  59.              variation->startPosition.activeColor);
  60.       free(pvMoves);
  61.       break;
  62.  
  63.    default:
  64.       break;
  65.    }
  66. }
  67.  
  68. static bool solveMateProblem(SearchTask * entry)
  69. {
  70.    bool result = TRUE;
  71.    int i;
  72.  
  73.    completeTask(entry);
  74.  
  75.    if (entry->solutions.numberOfMoves !=
  76.        entry->calculatedSolutions.numberOfMoves)
  77.    {
  78.       result = FALSE;
  79.    }
  80.  
  81.    for (i = 0; i < entry->solutions.numberOfMoves; i++)
  82.    {
  83.       if (listContainsMove
  84.           (&entry->calculatedSolutions, entry->solutions.moves[i]) == FALSE)
  85.       {
  86.          result = FALSE;
  87.       }
  88.    }
  89.  
  90.    return result;
  91. }
  92.  
  93. static bool solveBestMoveProblem(SearchTask * entry)
  94. {
  95.    completeTask(entry);
  96.  
  97.    return listContainsMove(&entry->solutions, entry->bestMove);
  98. }
  99.  
  100. static bool dumpEvaluation(SearchTask * entry)
  101. {
  102.    EvaluationBase base;
  103.  
  104.    prepareSearch(entry->variation);
  105.    getValue(&entry->variation->startPosition,
  106.             &base,
  107.             entry->variation->pawnHashtable,
  108.             entry->variation->kingsafetyHashtable);
  109.  
  110.    return TRUE;
  111. }
  112.  
  113. int processTestsuite(const char *filename)
  114. {
  115.    PGNFile pgnfile;
  116.    PGNGame *game;
  117.    SearchTask entry;
  118.    Gamemove *gamemove;
  119.    long i;
  120.    UINT64 overallNodes = 0;
  121.    const char *fmt = "\nTestsuite '%s': %d/%d solved, %s nodes\n";
  122.    char ons[32];
  123.    int solved = 0;
  124.    String notSolved = getEmptyString();
  125.    Variation variation;
  126.  
  127.    if (openPGNFile(&pgnfile, filename) != 0)
  128.    {
  129.       return -1;
  130.    }
  131.  
  132.    logReport("\nProcessing file '%s' [%ld game(s)]\n", filename,
  133.              pgnfile.numGames);
  134.  
  135.    statCount1 = statCount2 = 0;
  136.    variation.timeTarget = 60 * 1000;
  137.    variation.timeLimit = 60 * 1000;
  138.    variation.ponderMode = FALSE;
  139.    entry.variation = &variation;
  140.  
  141.    for (i = 1; i <= pgnfile.numGames; i++)
  142.    {
  143.       game = getGame(&pgnfile, i);
  144.  
  145.       if (game == 0)
  146.       {
  147.          continue;
  148.       }
  149.  
  150.       logReport("\n%ld (%ld): %s-%s\n", i, pgnfile.numGames,
  151.                 game->white, game->black);
  152.       logPosition(&game->firstMove->position);
  153.  
  154.       entry.solutions.numberOfMoves = 0;
  155.       gamemove = game->firstMove;
  156.  
  157.       while (gamemove != 0)
  158.       {
  159.          entry.solutions.moves
  160.             [entry.solutions.numberOfMoves++] =
  161.             getPackedMove(gamemove->from, gamemove->to, gamemove->newPiece);
  162.  
  163.          gamemove = gamemove->alternativeMove;
  164.       }
  165.  
  166.       initializeVariation(&variation, game->fen);
  167.       resetSharedHashtable = TRUE;
  168.       variation.handleSearchEvent = &handleSearchEvent;
  169.  
  170.       if (strstr(game->white, "[#") != NULL)
  171.       {
  172.          char *tmp = strstr(game->white, "[#");
  173.  
  174.          entry.type = TASKTYPE_TEST_MATE_IN_N;
  175.          entry.numberOfMoves = atoi(tmp + 2);
  176.  
  177.          if (solveMateProblem(&entry) != FALSE)
  178.          {
  179.             solved++;
  180.          }
  181.          else
  182.          {
  183.             assert(0);
  184.          }
  185.  
  186.          overallNodes += entry.nodes;
  187.       }
  188.       else
  189.       {
  190.          entry.type = TASKTYPE_TEST_BEST_MOVE;
  191.          entry.numberOfMoves = 0;
  192.  
  193.          if (commandlineOptions.dumpEvaluation)
  194.          {
  195.             dumpEvaluation(&entry);
  196.          }
  197.          else
  198.          {
  199.             if (solveBestMoveProblem(&entry) != FALSE)
  200.             {
  201.                solved++;
  202.             }
  203.             else
  204.             {
  205.                appendToString(&notSolved, "%d ", i);
  206.             }
  207.  
  208.             overallNodes += entry.nodes;
  209.          }
  210.       }
  211.  
  212.       freePgnGame(game);
  213.    }
  214.  
  215.    formatLongInteger(overallNodes, ons);
  216.    logReport(fmt, filename, solved, pgnfile.numGames, ons);
  217.    logReport("Not solved: %s\n", notSolved.buffer);
  218.    free(notSolved.buffer);
  219.    closePGNFile(&pgnfile);
  220.  
  221.    return 0;
  222. }
  223.  
  224. /**
  225.  * Initialize this module.
  226.  *
  227.  * @return 0 if no errors occurred.
  228.  */
  229. int initializeModuleTest(void)
  230. {
  231.    return 0;
  232. }
  233.  
  234. int testModuleTest()
  235. {
  236.    int result;
  237.  
  238.    if ((result = processTestsuite("moduletest.pgn")) != 0)
  239.    {
  240.       return result;
  241.    }
  242.  
  243.    return 0;
  244. }
  245.