Line data Source code
1 : #include "com.hpp"
2 : #include "position.hpp"
3 : #include "searcher.hpp"
4 :
5 4946510 : bool Searcher::isRep(const Position& p, bool isPV) const {
6 : // handles chess variants
7 4946510 : const int limit = isPV ? 2 : 1;
8 4946510 : if (p.fifty < (2 * limit - 1)) return false;
9 : int count = 0;
10 3084791 : const Hash h = computeHash(p);
11 3084791 : int k = p.halfmoves - 4;
12 : bool irreversible = false;
13 : //std::cout << "***************** " << k << " " << h << " " << GetFEN(p) << std::endl;
14 : // look in stack first
15 7850888 : for ( ; k >= 0; k-=2) {
16 : //std::cout << "stack " << k << " " << stack[k].h << " " << count << " " << ToString(stack[k].p.lastMove) << " " << GetFEN(stack[k].p) << std::endl;
17 7671769 : if (stack[k].h == nullHash) break; // no more "history" in stack (will look at game state later)
18 7468822 : if (stack[k].h == h){
19 : #ifdef DEBUG_FIFTY_COLLISION
20 : if (stack[k].p != p){
21 : Logging::LogIt(Logging::logFatal) << "Collision in fifty hash comparation" << ToString(p) << ToString(stack[k].p);
22 : }
23 : #endif
24 6943 : ++count;
25 6943 : if (count >= limit){
26 : //std::cout << "draw" << std::endl;
27 : return true;
28 : }
29 : }
30 : // irreversible moves - check both k-1 and k positions
31 7462271 : if (k > 0) {
32 7462271 : const Move prevMove = stack[k-1].p.lastMove;
33 4581789 : if (isValidMove(prevMove) &&
34 11860795 : (isCapture(prevMove) || PieceTools::getPieceType(stack[k-1].p, Move2To(prevMove)) == P_wp)){
35 : irreversible=true;
36 : break;
37 : }
38 : }
39 5593100 : const Move curMove = stack[k].p.lastMove;
40 2897997 : if (isValidMove(curMove) &&
41 8178969 : (isCapture(curMove) || PieceTools::getPieceType(stack[k].p, Move2To(curMove)) == P_wp)){
42 : irreversible=true;
43 : break;
44 : }
45 : }
46 : // then double check in game history
47 3078240 : while(!irreversible && k>=0){
48 202947 : const std::optional<Hash> curh = COM::GetGameInfo().getHash(k);
49 202947 : if (!curh.has_value()) break;
50 : //std::cout << "history " << k << " " << curh.value() << " " << count << " " << ToString(COM::GetGameInfo().getMove(k).value()) << " " << GetFEN(COM::GetGameInfo().getPosition(k).value()) << std::endl;
51 0 : if (curh.value() == h){
52 0 : ++count;
53 0 : if (count >= limit){
54 : //std::cout << "draw" << std::endl;
55 0 : return true;
56 : }
57 : }
58 : // irreversible moves - check both k-1 and k
59 0 : if (k>0){
60 0 : const auto m = COM::GetGameInfo().getMove(k-1);
61 0 : if (m.has_value()){
62 0 : const Move move = m.value();
63 0 : if (isCapture(move)){
64 : irreversible=true;
65 0 : break;
66 : }
67 0 : const auto pp = COM::GetGameInfo().getPosition(k-1);
68 0 : if (pp.has_value() && PieceTools::getPieceType(pp.value(), Move2To(move)) == P_wp){
69 : irreversible=true;
70 : break;
71 : }
72 : }
73 : }
74 0 : const auto m = COM::GetGameInfo().getMove(k);
75 0 : if (m.has_value()){
76 0 : const Move move = m.value();
77 0 : if (isCapture(move)){
78 : irreversible=true;
79 0 : break;
80 : }
81 0 : const auto pp = COM::GetGameInfo().getPosition(k);
82 0 : if (pp.has_value() && PieceTools::getPieceType(pp.value(), Move2To(move)) == P_wp){
83 : irreversible=true;
84 : break;
85 : }
86 : }
87 0 : k-=2;
88 : }
89 : return false;
90 : }
91 :
92 4939959 : bool Searcher::isMaterialDraw(const Position& p) const{
93 : // handles chess variants
94 4939959 : if ( (p.occupancy() & ~p.allKing()) == emptyBitBoard) return true;
95 4939959 : const auto ter = ( (p.mat[Co_White][M_p] + p.mat[Co_Black][M_p]) < 2) ? MaterialHash::probeMaterialHashTable(p.mat) : MaterialHash::Terminaison::Ter_Unknown;
96 4939959 : return ter == MaterialHash::Terminaison::Ter_Draw || ter == MaterialHash::Terminaison::Ter_MaterialDraw;
97 : }
98 :
99 7239395 : bool Searcher::is50moves(const Position& p, bool afterMoveLoop) const{
100 : // handles chess variants
101 : // checking 50MR at 100 or 101 depending on being before or after move loop because it might be reset by checkmate
102 7239395 : return p.fifty >= 100 + afterMoveLoop;
103 : }
|