- /* 
-     Texel - A UCI chess engine. 
-     Copyright (C) 2012-2013  Peter Ă–sterlund, peterosterlund2@gmail.com 
-   
-     This program is free software: you can redistribute it and/or modify 
-     it under the terms of the GNU General Public License as published by 
-     the Free Software Foundation, either version 3 of the License, or 
-     (at your option) any later version. 
-   
-     This program is distributed in the hope that it will be useful, 
-     but WITHOUT ANY WARRANTY; without even the implied warranty of 
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
-     GNU General Public License for more details. 
-   
-     You should have received a copy of the GNU General Public License 
-     along with this program.  If not, see <http://www.gnu.org/licenses/>. 
- */ 
-   
- /* 
-  * history.hpp 
-  * 
-  *  Created on: Feb 25, 2012 
-  *      Author: petero 
-  */ 
-   
- #ifndef HISTORY_HPP_ 
- #define HISTORY_HPP_ 
-   
- #include "piece.hpp" 
- #include "position.hpp" 
-   
- /** 
-  * Implements the relative history heuristic. 
-  */ 
- class History { 
- public: 
-     History(); 
-   
-     /** Clear all history information. */ 
-     void init(); 
-   
-     /** Rescale the history counters, so that future updates have more weight. */ 
-     void reScale(); 
-   
-     /** Record move as a success. */ 
-     void addSuccess(const Position& pos, const Move& m, int depth); 
-   
-     /** Record move as a failure. */ 
-     void addFail(const Position& pos, const Move& m, int depth); 
-   
-     /** Get a score between 0 and 49, depending of the success/fail ratio of the move. */ 
-     int getHistScore(const Position& pos, const Move& m) const; 
-   
- private: 
-     static int depthWeight(int depth); 
-   
-     static int depthTable[6]; 
-   
-     struct Entry { 
-         RelaxedShared<int> countSuccess; 
-         RelaxedShared<int> countFail; 
-         mutable RelaxedShared<int> score; 
-     }; 
-     Entry ht[Piece::nPieceTypes][64]; 
- }; 
-   
-   
- inline 
- History::History() { 
-     init(); 
- } 
-   
- inline int 
- History::depthWeight(int depth) { 
-     return depthTable[clamp(depth, 0, (int)COUNT_OF(depthTable)-1)]; 
- } 
-   
- inline void 
- History::addSuccess(const Position& pos, const Move& m, int depth) { 
-     int p = pos.getPiece(m.from()); 
-     int cnt = depthWeight(depth); 
-     Entry& e = ht[p][m.to()]; 
-     int val = e.countSuccess + cnt; 
-     if (val + e.countFail > 1300) { 
-         val /= 2; 
-         e.countFail = e.countFail / 2; 
-     } 
-     e.countSuccess = val; 
-     e.score = -1; 
- } 
-   
- inline void 
- History::addFail(const Position& pos, const Move& m, int depth) { 
-     int p = pos.getPiece(m.from()); 
-     int cnt = depthWeight(depth); 
-     Entry& e = ht[p][m.to()]; 
-     int val = e.countFail + cnt; 
-     if (val + e.countSuccess > 1300) { 
-         val /= 2; 
-         e.countSuccess = e.countSuccess / 2; 
-     } 
-     e.countFail = val; 
-     e.score = -1; 
- } 
-   
- inline int 
- History::getHistScore(const Position& pos, const Move& m) const { 
-     int p = pos.getPiece(m.from()); 
-     const Entry& e = ht[p][m.to()]; 
-     int ret = e.score; 
-     if (ret >= 0) 
-         return ret; 
-     int succ = e.countSuccess; 
-     int fail = e.countFail; 
-     if (succ + fail > 0) { 
-         ret = succ * 49 / (succ + fail); 
-     } else 
-         ret = 0; 
-     e.score = ret; 
-     return ret; 
- } 
-   
- #endif /* HISTORY_HPP_ */ 
-