1 #include "chess.h"
2 #include "data.h"
3 /* last modified 08/03/16 */
4 /*
5 *******************************************************************************
6 * *
7 * ResignOrDraw() is used to determine if the program should either resign *
8 * or offer a draw. This decision is based on two criteria: (1) current *
9 * search evaluation and (2) time remaining on opponent's clock. *
10 * *
11 * The evaluation returned by the last search must be less than the resign *
12 * threshold to trigger the resign code, or else must be exactly equal to *
13 * the draw score to trigger the draw code. *
14 * *
15 * The opponent must have enough time to be able to win or draw the game if *
16 * it were played out as well. *
17 * *
18 *******************************************************************************
19 */
ResignOrDraw(TREE * RESTRICT tree,int value)20 void ResignOrDraw(TREE * RESTRICT tree, int value) {
21 int v, result = 0;
22
23 /*
24 ************************************************************
25 * *
26 * If the game is a technical draw, where there are no *
27 * pawns and material is balanced, then offer a draw. *
28 * *
29 ************************************************************
30 */
31 if (Drawn(tree, value) == 1)
32 result = 2;
33 /*
34 ************************************************************
35 * *
36 * First check to see if the increment is 2 seconds or *
37 * more. If so, then the game is being played slowly *
38 * enough that a draw offer or resignation is worth *
39 * consideration. Otherwise, if the opponent has at least *
40 * 30 seconds left, he can probably play the draw or win *
41 * out. *
42 * *
43 * If the value is below the resignation threshold, then *
44 * Crafty should resign and get on to the next game. Note *
45 * that it is necessary to have a bad score for *
46 * <resign_count> moves in a row before resigning. *
47 * *
48 * Note that we don't resign for "deep mates" since we do *
49 * not know if the opponent actually saw that result. We *
50 * play on until it becomes obvious he "sees it." *
51 * *
52 ************************************************************
53 */
54 if ((tc_increment > 200) || (tc_time_remaining[Flip(root_wtm)] >= 3000)) {
55 if (resign) {
56 if (value < -(MATE - 15)) {
57 if (++resign_counter >= resign_count)
58 result = 1;
59 } else if (value < -resign * 100 && value > -32000) {
60 if (++resign_counter >= resign_count)
61 result = 1;
62 } else
63 resign_counter = 0;
64 }
65 }
66 /*
67 ************************************************************
68 * *
69 * If the value is almost equal to the draw score, then *
70 * Crafty should offer the opponent a draw. Note that it *
71 * is necessary that the draw score occur on exactly *
72 * <draw_count> moves in a row before making the offer. *
73 * Note also that the draw offer will be repeated every *
74 * <draw_count> moves so setting this value too low can *
75 * make the program behave "obnoxiously." *
76 * *
77 ************************************************************
78 */
79 if ((tc_increment > 200) || (tc_time_remaining[Flip(root_wtm)] >= 3000)) {
80 if (Abs(Abs(value) - Abs(DrawScore(game_wtm))) < 2 &&
81 moves_out_of_book > 3) {
82 if (++draw_counter >= draw_count) {
83 draw_counter = 0;
84 result = 2;
85 }
86 } else
87 draw_counter = 0;
88 }
89 /*
90 ************************************************************
91 * *
92 * Now print the draw offer or resignation if appropriate *
93 * but be sure and do it in a form that ICC/FICS will *
94 * understand if the "xboard" flag is set. *
95 * *
96 * Note that we also use the "speak" facility to verbally *
97 * offer draws or resign if the "speech" variable has been *
98 * set to 1 by entering "speech on". *
99 * *
100 ************************************************************
101 */
102 if (result == 1) {
103 learn_value = (crafty_is_white) ? -300 : 300;
104 LearnBook();
105 if (xboard)
106 Print(4095, "resign\n");
107 if (audible_alarm)
108 printf("%c", audible_alarm);
109 if (speech) {
110 char announce[128];
111
112 strcpy(announce, "./speak ");
113 strcat(announce, "Resign");
114 v = system(announce);
115 if (v <= 0)
116 perror("ResignOrDraw() system() error: ");
117 }
118 if (crafty_is_white) {
119 Print(4095, "0-1 {White resigns}\n");
120 strcpy(pgn_result, "0-1");
121 } else {
122 Print(4095, "1-0 {Black resigns}\n");
123 strcpy(pgn_result, "1-0");
124 }
125 }
126 if (offer_draws && result == 2) {
127 draw_offered = 1;
128 if (!xboard) {
129 Print(1, "\nI offer a draw.\n\n");
130 if (audible_alarm)
131 printf("%c", audible_alarm);
132 if (speech) {
133 char announce[128];
134
135 strcpy(announce, "./speak ");
136 strcat(announce, "Drawoffer");
137 v = system(announce);
138 if (v <= 0)
139 perror("ResignOrDraw() system() error: ");
140 }
141 } else if (xboard)
142 Print(4095, "offer draw\n");
143 else
144 Print(4095, "\n*draw\n");
145 } else
146 draw_offered = 0;
147 }
148