Subversion Repositories Games.Chess Giants

Rev

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

  1. /*
  2.     Texel - A UCI chess engine.
  3.     Copyright (C) 2012-2014  Peter Ă–sterlund, peterosterlund2@gmail.com
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. /*
  20.  * computerPlayer.cpp
  21.  *
  22.  *  Created on: Feb 25, 2012
  23.  *      Author: petero
  24.  */
  25.  
  26. #include "computerPlayer.hpp"
  27. #include "textio.hpp"
  28. #include "tbprobe.hpp"
  29.  
  30. #include <iostream>
  31.  
  32. std::string ComputerPlayer::engineName;
  33.  
  34.  
  35. static StaticInitializer<ComputerPlayer> cpInit;
  36.  
  37. void
  38. ComputerPlayer::staticInitialize() {
  39.     std::string name = "Texel 1.05";
  40.     if (sizeof(char*) == 4)
  41.         name += " 32-bit";
  42.     if (sizeof(char*) == 8)
  43.         name += " 64-bit";
  44.     engineName = name;
  45. }
  46.  
  47. void
  48. ComputerPlayer::initEngine() {
  49.     Parameters::instance();
  50.  
  51.     auto tbInit = []() {
  52.         TBProbe::initialize(UciParams::gtbPath->getStringPar(),
  53.                             UciParams::gtbCache->getIntPar(),
  54.                             UciParams::rtbPath->getStringPar());
  55.     };
  56.     UciParams::gtbPath->addListener(tbInit);
  57.     UciParams::gtbCache->addListener(tbInit, false);
  58.     UciParams::rtbPath->addListener(tbInit, false);
  59.  
  60.     knightMobScore.addListener(Evaluate::updateEvalParams);
  61.     castleFactor.addListener(Evaluate::updateEvalParams, false);
  62.     pV.addListener([]() { pieceValue[Piece::WPAWN]   = pieceValue[Piece::BPAWN]   = pV; });
  63.     nV.addListener([]() { pieceValue[Piece::WKNIGHT] = pieceValue[Piece::BKNIGHT] = nV; });
  64.     bV.addListener([]() { pieceValue[Piece::WBISHOP] = pieceValue[Piece::BBISHOP] = bV; });
  65.     rV.addListener([]() { pieceValue[Piece::WROOK]   = pieceValue[Piece::BROOK]   = rV; });
  66.     qV.addListener([]() { pieceValue[Piece::WQUEEN]  = pieceValue[Piece::BQUEEN]  = qV; });
  67.     kV.addListener([]() { pieceValue[Piece::WKING]   = pieceValue[Piece::BKING]   = kV; });
  68. }
  69.  
  70. ComputerPlayer::ComputerPlayer()
  71.     : tt(15), pd(tt),
  72.       book(false)
  73. {
  74.     initEngine();
  75.     et = Evaluate::getEvalHashTables();
  76.     minTimeMillis = 10000;
  77.     maxTimeMillis = 10000;
  78.     maxDepth = 100;
  79.     maxNodes = -1;
  80.     verbose = true;
  81.     bookEnabled = true;
  82.     currentSearch = nullptr;
  83. }
  84.  
  85. std::string
  86. ComputerPlayer::getCommand(const Position& posIn, bool drawOffer, const std::vector<Position>& history) {
  87.     // Create a search object
  88.     std::vector<U64> posHashList(200 + history.size());
  89.     int posHashListSize = 0;
  90.     for (size_t i = 0; i < history.size(); i++)
  91.         posHashList[posHashListSize++] = history[i].zobristHash();
  92.     tt.nextGeneration();
  93.     Position pos(posIn);
  94.     KillerTable kt;
  95.     History ht;
  96.     Search::SearchTables st(tt, kt, ht, *et);
  97.     TreeLogger treeLog;
  98.     Search sc(pos, posHashList, posHashListSize, st, pd, nullptr, treeLog);
  99.  
  100.     // Determine all legal moves
  101.     MoveList moves;
  102.     MoveGen::pseudoLegalMoves(pos, moves);
  103.     MoveGen::removeIllegal(pos, moves);
  104.     sc.scoreMoveList(moves, 0);
  105.  
  106.     // Test for "game over"
  107.     if (moves.size == 0) {
  108.         // Switch sides so that the human can decide what to do next.
  109.         return "swap";
  110.     }
  111.  
  112.     if (bookEnabled) {
  113.         Move bookMove;
  114.         book.getBookMove(pos, bookMove);
  115.         if (!bookMove.isEmpty()) {
  116.             std::cout << "Book moves: " << book.getAllBookMoves(pos) << std::endl;
  117.             return TextIO::moveToString(pos, bookMove, false);
  118.         }
  119.     }
  120.  
  121.     // Find best move using iterative deepening
  122.     currentSearch = &sc;
  123.     sc.setListener(listener);
  124.     Move bestM;
  125.     if ((moves.size == 1) && (canClaimDraw(pos, posHashList, posHashListSize, moves[0]) == "")) {
  126.         bestM = moves[0];
  127.         bestM.setScore(0);
  128.     } else {
  129.         sc.timeLimit(minTimeMillis, maxTimeMillis);
  130.         bestM = sc.iterativeDeepening(moves, maxDepth, maxNodes, verbose, 1, false, 100);
  131.     }
  132.     currentSearch = nullptr;
  133.     //        tt.printStats();
  134.     std::string strMove = TextIO::moveToString(pos, bestM, false);
  135.  
  136.     // Claim draw if appropriate
  137.     if (bestM.score() <= 0) {
  138.         std::string drawClaim = canClaimDraw(pos, posHashList, posHashListSize, bestM);
  139.         if (drawClaim != "")
  140.             strMove = drawClaim;
  141.     }
  142.     return strMove;
  143. }
  144.  
  145. std::string
  146. ComputerPlayer::canClaimDraw(Position& pos, std::vector<U64>& posHashList,
  147.                              int posHashListSize, const Move& move) {
  148.     std::string drawStr;
  149.     if (Search::canClaimDraw50(pos)) {
  150.         drawStr = "draw 50";
  151.     } else if (Search::canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize)) {
  152.         drawStr = "draw rep";
  153.     } else {
  154.         std::string strMove = TextIO::moveToString(pos, move, false);
  155.         posHashList[posHashListSize++] = pos.zobristHash();
  156.         UndoInfo ui;
  157.         pos.makeMove(move, ui);
  158.         if (Search::canClaimDraw50(pos)) {
  159.             drawStr = "draw 50 " + strMove;
  160.         } else if (Search::canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize)) {
  161.             drawStr = "draw rep " + strMove;
  162.         }
  163.         pos.unMakeMove(move, ui);
  164.     }
  165.     return drawStr;
  166. }
  167.  
  168. void
  169. ComputerPlayer::timeLimit(int minTimeLimit, int maxTimeLimit) {
  170.     minTimeMillis = minTimeLimit;
  171.     maxTimeMillis = maxTimeLimit;
  172.     if (currentSearch != nullptr)
  173.         currentSearch->timeLimit(minTimeLimit, maxTimeLimit);
  174. }
  175.  
  176. std::pair<Move, std::string>
  177. ComputerPlayer::searchPosition(Position& pos, int maxTimeMillis) {
  178.     // Create a search object
  179.     std::vector<U64> posHashList(200);
  180.     tt.nextGeneration();
  181.     KillerTable kt;
  182.     History ht;
  183.     Search::SearchTables st(tt, kt, ht, *et);
  184.     TreeLogger treeLog;
  185.     Search sc(pos, posHashList, 0, st, pd, nullptr, treeLog);
  186.  
  187.     // Determine all legal moves
  188.     MoveList moves;
  189.     MoveGen::pseudoLegalMoves(pos, moves);
  190.     MoveGen::removeIllegal(pos, moves);
  191.     sc.scoreMoveList(moves, 0);
  192.  
  193.     // Find best move using iterative deepening
  194.     sc.timeLimit(maxTimeMillis, maxTimeMillis);
  195.     Move bestM = sc.iterativeDeepening(moves, -1, -1, false);
  196.  
  197.     // Extract PV
  198.     std::string PV = TextIO::moveToString(pos, bestM, false) + " ";
  199.     UndoInfo ui;
  200.     pos.makeMove(bestM, ui);
  201.     PV += tt.extractPV(pos);
  202.     pos.unMakeMove(bestM, ui);
  203.  
  204. //    tt.printStats();
  205.  
  206.     // Return best move and PV
  207.     return std::pair<Move, std::string>(bestM, PV);
  208. }
  209.