slightly smaller pluto
[rattatechess.git] / draw.cpp
blob2cfb1e476b7bb9b328d932ba8fb47186784aacbd
1 /***************************************************************************
2 draw.cpp - Draw recognition
3 -------------------
4 begin : Sun Sep 28 2007
5 copyright : (C) 2007 by Maurizio Monge
6 email : monge@linuz.sns.it
7 ***************************************************************************/
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
18 #include "engine.h"
19 #include "search.h"
21 /* check if the position can be considered draw for 50mvs rule or repetition */
22 bool Engine::check_draw()
24 if(board.fifty >= 100) /* 50mvs rule */
25 return true;
27 return board.insufficient_material() || check_repetition(2);
30 bool Engine::check_repetition(int nfold)
32 /* for the latest reversible moves check if the hash value
33 (for this player) is the same */
34 int first_candidate = MAX(save_buf_num - board.fifty, 0);
36 /* -4 because it is impossible that the previous position is
37 equal to the current one :) */
38 for(int i=save_buf_num-4;i>=first_candidate;i-=2)
40 if(board.hash == save_buf[i].hash_key)
42 nfold--;
43 if(nfold <= 1)
44 return true;
48 return false;
51 /* check if the position can be considered draw for 50mvs rule or repetition */
52 bool SearchRoot::check_draw(int curr_ply)
54 if(board.fifty >= 100) /* 50mvs rule */
55 return true;
57 return board.insufficient_material() || check_repetition(curr_ply, 2);
60 bool SearchRoot::check_repetition(int curr_ply, int nfold)
62 int first_candidate1 = MAX(curr_ply - board.fifty, 0);
64 /* -4 because it is impossible that the previous position is
65 equal to the current one :) */
66 for(int i=curr_ply-4;i>=first_candidate1;i-=2)
68 if(board.hash == stack[i].save_buf.hash_key)
70 nfold--;
71 if(nfold <= 1)
72 return true;
76 int first_candidate2 = MAX(engine->save_buf_num + curr_ply - (board.fifty & ~1), 0);
78 /* -4 because it is impossible that the previous position is
79 equal to the current one :) */
80 for(int i=first_candidate2; i<engine->save_buf_num; i+=2)
82 if(board.hash == engine->save_buf[i].hash_key)
84 nfold--;
85 if(nfold <= 1)
86 return true;
90 return false;
93 bool Board::insufficient_material()
95 for(int i=0;i<2;i++)
97 int mt = (i ? 5 : -1);
99 if(mat_tracking[PAWN+mt].count > 0
100 || mat_tracking[QUEEN+mt].count > 0
101 || mat_tracking[ROOK+mt].count > 0)
102 return false;
104 /* ok, unless the 2 bishop are on squares of the same color :) */
105 if(mat_tracking[BISHOP+mt].count >= 2)
106 return false;
108 if(mat_tracking[KNIGHT+mt].count >= 1 &&
109 mat_tracking[BISHOP+mt].count >= 1)
110 return false;
112 /* 3 knights can checkmate :) */
113 if(mat_tracking[KNIGHT+mt].count >= 3)
114 return false;
116 return true;