1 #include "chess.h"
2 #include "data.h"
3 /* last modified 12/21/09 */
4 /*
5 *******************************************************************************
6 * *
7 * Drawn() is used to answer the question "is this position a hopeless *
8 * draw?" Several considerations are included in making this decision, but *
9 * the most basic one is simply the remaining material for each side. If *
10 * either side has pawns, it's not a draw. With no pawns, equal material is *
11 * a draw. Otherwise, the superior side must have enough material to be *
12 * able to force a mate. *
13 * *
14 * Drawn() has 3 possible return values: *
15 * *
16 * 0: Game is not a draw by rule or drawish in nature. *
17 * *
18 * 1: Game is a "technical draw" where material is even with no pawns and *
19 * the search is also returning draw scores as the best outcome. *
20 * *
21 * 2: Game is an "actual draw" by FIDE rules, such as KB vs K, where mate *
22 * can't be forced, even with worst possible play by one side. *
23 * *
24 *******************************************************************************
25 */
Drawn(TREE * RESTRICT tree,int value)26 int Drawn(TREE * RESTRICT tree, int value) {
27 /*
28 ************************************************************
29 * *
30 * If either side has pawns, the game is not a draw for *
31 * lack of material. *
32 * *
33 ************************************************************
34 */
35 if (TotalPieces(white, pawn) || TotalPieces(black, pawn))
36 return 0;
37 /*
38 ************************************************************
39 * *
40 * If the score suggests a mate has been found, this is *
41 * not a draw. *
42 * *
43 ************************************************************
44 */
45 if (MateScore(value))
46 return 0;
47 /*
48 ************************************************************
49 * *
50 * If neither side has pawns, and one side has some sort *
51 * of material superiority, then determine if the winning *
52 * side has enough material to win. *
53 * *
54 ************************************************************
55 */
56 if (TotalPieces(white, occupied) + TotalPieces(black, occupied) < 4)
57 return 2;
58 if (TotalPieces(white, occupied) < 5 && TotalPieces(black, occupied) < 5)
59 return 1;
60 if (TotalPieces(white, occupied) == 5 || TotalPieces(white, occupied) > 6)
61 return 0;
62 if (TotalPieces(black, occupied) == 5 || TotalPieces(black, occupied) > 6)
63 return 0;
64 if ((TotalPieces(white, occupied) == 6 && !Bishops(white) && Material > 0)
65 || (TotalPieces(black, occupied) == 6 && !Bishops(black)
66 && Material < 0))
67 return 1;
68 /*
69 ************************************************************
70 * *
71 * The search result must indicate a draw also, otherwise *
72 * it could be a tactical win or loss, so we will skip *
73 * calling an equal material (no pawns) position a draw to *
74 * make sure there is no mate that the search sees. *
75 * *
76 * If neither side has pawns, then one side must have some *
77 * sort of material superiority, otherwise it is a draw. *
78 * *
79 ************************************************************
80 */
81 if (value != DrawScore(game_wtm))
82 return 0;
83 if (TotalPieces(white, occupied) == TotalPieces(black, occupied))
84 return 1;
85 return 0;
86 }
87