4 * ----------------------------------------------------------------------
6 * Copyright (c) 2012 Free Software Foundation
8 * GNU SHOGI is based on GNU CHESS
10 * This file is part of GNU SHOGI.
12 * GNU Shogi is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 3 of the License,
15 * or (at your option) any later version.
17 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * You should have received a copy of the GNU General Public License along
23 * with GNU Shogi; see the file COPYING. If not, see
24 * <http://www.gnu.org/licenses/>.
25 * ----------------------------------------------------------------------
33 #define ALTERNATIVE_TC
37 * In a networked enviroment gnushogi might be compiled on different hosts
38 * with different random number generators; that is not acceptable if they
39 * are going to share the same transposition table.
42 static unsigned long next
= 1;
49 return ((unsigned int) (next
>> 16) & 0xFFFF);
55 gsrand(unsigned int seed
)
65 /* adjust number of moves remaining in gamein games */
72 /* Don't do anything until you have enough numbers. */
73 if (GameCnt
< (MINGAMEIN
* 2))
76 /* Calculate average time in sec for last MINGAMEIN moves. */
77 for (i
= 0; i
< MINGAMEIN
; i
++)
79 tcompsum
+= timecomp
[i
];
83 topsum
/= (100 * MINGAMEIN
);
84 tcompsum
/= (100 * MINGAMEIN
);
86 /* If I have less time than opponent add another move. */
87 me
= TimeControl
.clock
[computer
] / 100;
88 him
= TimeControl
.clock
[opponent
] / 100;
93 if (((him
- me
) > 60) || ((me
< him
) && (me
< 120)))
96 /* If I am losing more time with each move add another. */
97 /* If (!((me - him) > 60) && tcompsum > topsum) increment++; */
99 if (tcompsum
> topsum
)
103 else if ((TimeControl
.moves
[computer
] < MINMOVES
) && !increment
)
105 /* ... but don't let moves go below MINMOVES. */
108 else if ((me
> him
) && (tcompsum
< topsum
))
110 /* If I am doing really well use more time per move. */
114 /* If not fischer clock be careful about time. */
115 /* CHECKME: what's a fischer clock? */
117 if ((TCadd
== 0) && (increment
> 0))
120 if ((me
== 0) && (increment
> 0))
123 TimeControl
.moves
[computer
] += increment
;
129 * Set ResponseTime, TCcount, and TCleft.
132 void SetResponseTime(short side
)
134 #ifdef ALTERNATIVE_TC
135 int DetermineTCcount
= true;
141 if (TimeControl
.moves
[side
] < 1)
142 TimeControl
.moves
[side
] = 1;
144 /* special case time per move specified */
147 ResponseTime
= TimeControl
.clock
[side
] - 100;
152 /* calculate avg time per move remaining */
153 if (TimeControl
.clock
[side
] <= 0)
156 TCleft
= (long)MINRESPONSETIME
/ MAXTCCOUNTX
;
160 short rtf
= in_opening_stage
? 8 : 2;
161 short tcq
= in_opening_stage
? 2 : 4;
163 TimeControl
.clock
[side
] += TCadd
;
164 ResponseTime
= (TimeControl
.clock
[side
])
165 / (((TimeControl
.moves
[side
]) * rtf
) + 1);
166 TCleft
= (long)ResponseTime
/ tcq
;
167 ResponseTime
+= TCadd
/ 2;
170 if (TimeControl
.moves
[side
] < 5)
172 TCcount
= MAXTCCOUNTX
- 10;
177 DetermineTCcount
= false;
181 if (ResponseTime
< MINRESPONSETIME
)
183 ResponseTime
= MINRESPONSETIME
;
184 TCcount
= MAXTCCOUNTX
- 10;
189 DetermineTCcount
= false;
192 if (!hard_time_limit
&& (ResponseTime
< 2 * MINRESPONSETIME
))
194 TCcount
= MAXTCCOUNTX
- 10;
199 DetermineTCcount
= false;
205 ResponseTime
= MaxResponseTime
;
206 ElapsedTime(COMPUTE_AND_INIT_MODE
);
209 if (DetermineTCcount
)
214 = ((int)((TimeControl
.clock
[side
] - ResponseTime
)) / 2)
217 if (AllowedCounts
<= 0)
218 TCcount
= MAXTCCOUNTX
;
219 else if (AllowedCounts
> MAXTCCOUNTX
)
222 TCcount
= MAXTCCOUNTX
- AllowedCounts
;
226 TCcount
= MAXTCCOUNTX
;
230 if (ResponseTime
< MINRESPONSETIME
)
231 ResponseTime
= MINRESPONSETIME
;
239 if (TimeControl
.moves
[side
] < 1)
240 TimeControl
.moves
[side
] = 1;
242 /* special case time per move specified */
245 ResponseTime
= TimeControl
.clock
[side
] - 100;
250 /* calculate avg time per move remaining */
251 TimeControl
.clock
[side
] += TCadd
;
253 ResponseTime
= (TimeControl
.clock
[side
])
254 / (((TimeControl
.moves
[side
]) * 2) + 1);
255 TCleft
= (int) ResponseTime
/ 3;
256 ResponseTime
+= TCadd
/ 2;
258 if (TimeControl
.moves
[side
] < 5)
259 TCcount
= MAXTCCOUNTX
- 10;
262 if (ResponseTime
< 101)
265 TCcount
= MAXTCCOUNTX
- 10;
267 else if (ResponseTime
< 200)
269 TCcount
= MAXTCCOUNTX
- 10;
274 ResponseTime
= MaxResponseTime
;
276 ElapsedTime(COMPUTE_AND_INIT_MODE
);
281 TCcount
= ((int)((TimeControl
.clock
[side
] - ResponseTime
)) / 2)
284 if (TCcount
> MAXTCCOUNTX
)
287 TCcount
= MAXTCCOUNTX
- TCcount
;
291 TCcount
= MAXTCCOUNTX
;
295 assert(TCcount
<= MAXTCCOUNTX
);
301 CheckForTimeout(int score
, int globalscore
, int Jscore
, int zwndw
)
303 if (flag
.musttimeout
|| (Sdepth
>= MaxSearchDepth
))
306 else if (TCflag
&& (Sdepth
> (MINDEPTH
- 1)) && (TCcount
< MAXTCCOUNTR
))
308 if (killr0
[1] != PrVar
[1] /* || Killr0[2] != PrVar[2] */)
314 if ((TCcount
< MAXTCCOUNTR
)
315 && (abs(score
- globalscore
) / Sdepth
) > ZDELTA
)
322 if ((score
> (Jscore
- zwndw
)) && (score
> (Tree
[1].score
+ 250)))
325 ElapsedTime(COMPUTE_MODE
);
327 if (root
->flags
& exact
)
329 /*else if (Tree[1].score < -SCORE_LIMIT) flag.timeout = true;
331 #if defined OLDTIME || !defined HAVE_GETTIMEOFDAY
332 else if (!(Sdepth
< MINDEPTH
)
334 && ((4 * et
) > (2*ResponseTime
+ ExtraTime
)))
337 else if (!(Sdepth
< MINDEPTH
)
339 && ((int)(1.93913099l * (pow((double)et
, 1.12446928l)))
340 > (ResponseTime
+ ExtraTime
)))
345 ShowMessage("timeout");