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-2013  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.  * killerTable.hpp
  21.  *
  22.  *  Created on: Feb 25, 2012
  23.  *      Author: petero
  24.  */
  25.  
  26. #ifndef KILLERTABLE_HPP_
  27. #define KILLERTABLE_HPP_
  28.  
  29. #include "util/util.hpp"
  30. #include "move.hpp"
  31. #include <cassert>
  32.  
  33.  
  34. /**
  35.  * Implement a table of killer moves for the killer heuristic.
  36.  */
  37. class KillerTable {
  38. public:
  39.     /** Create an empty killer table. */
  40.     KillerTable();
  41.  
  42.     /** Clear killer table. */
  43.     void clear();
  44.  
  45.     /** Add a killer move to the table. Moves are replaced on an LRU basis. */
  46.     void addKiller(int ply, const Move& m);
  47.  
  48.     /**
  49.      * Get a score for move m based on hits in the killer table.
  50.      * The score is 4 for primary   hit at ply.
  51.      * The score is 3 for secondary hit at ply.
  52.      * The score is 2 for primary   hit at ply - 2.
  53.      * The score is 1 for secondary hit at ply - 2.
  54.      * The score is 0 otherwise.
  55.      */
  56.     int getKillerScore(int ply, const Move& m) const;
  57.  
  58. private:
  59.     /** There is one KTEntry for each ply in the search tree. */
  60.     struct KTEntry {
  61.         KTEntry();
  62.         RelaxedShared<int> move0;
  63.         RelaxedShared<int> move1;
  64.     };
  65.     KTEntry ktList[200];
  66. };
  67.  
  68. inline
  69. KillerTable::KillerTable() {
  70. }
  71.  
  72. inline
  73. KillerTable::KTEntry::KTEntry()
  74.     : move0(0), move1(0) {
  75. }
  76.  
  77. inline void
  78. KillerTable::addKiller(int ply, const Move& m) {
  79.     if (ply >= (int)COUNT_OF(ktList))
  80.         return;
  81.     int move = (short)(m.from() + (m.to() << 6) + (m.promoteTo() << 12));
  82.     KTEntry& ent = ktList[ply];
  83.     if (move != ent.move0) {
  84.         ent.move1 = ent.move0;
  85.         ent.move0 = move;
  86.     }
  87. }
  88.  
  89. inline int
  90. KillerTable::getKillerScore(int ply, const Move& m) const {
  91.     int move = (short)(m.from() + (m.to() << 6) + (m.promoteTo() << 12));
  92.     if (ply < (int)COUNT_OF(ktList)) {
  93.         const KTEntry& ent = ktList[ply];
  94.         if (move == ent.move0) {
  95.             return 4;
  96.         } else if (move == ent.move1) {
  97.             return 3;
  98.         }
  99.     }
  100.     if ((ply - 2 >= 0) && (ply - 2 < (int)COUNT_OF(ktList))) {
  101.         const KTEntry& ent = ktList[ply - 2];
  102.         if (move == ent.move0) {
  103.             return 2;
  104.         } else if (move == ent.move1) {
  105.             return 1;
  106.         }
  107.     }
  108.     return 0;
  109. }
  110.  
  111. #endif /* KILLERTABLE_HPP_ */
  112.