Long-dead code removal: unused macro
[gnushogi.git] / gnushogi / tcontrl.c
blob99f33f82c68d44de3b0c1f1e57327b35c9a886ea
1 /*
2 * FILE: tcontrl.c
4 * ----------------------------------------------------------------------
5 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
7 * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
9 * GNU SHOGI is based on GNU CHESS
11 * Copyright (c) 1988, 1989, 1990 John Stanback
12 * Copyright (c) 1992 Free Software Foundation
14 * This file is part of GNU SHOGI.
16 * GNU Shogi is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 3 of the License,
19 * or (at your option) any later version.
21 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with GNU Shogi; see the file COPYING. If not, see
28 * <http://www.gnu.org/licenses/>.
29 * ----------------------------------------------------------------------
34 #include "gnushogi.h"
35 #include <math.h>
39 * In a networked enviroment gnushogi might be compiled on different hosts
40 * with different random number generators; that is not acceptable if they
41 * are going to share the same transposition table.
44 static unsigned long next = 1;
46 unsigned int
47 urand(void)
49 next *= 1103515245;
50 next += 12345;
51 return ((unsigned int) (next >> 16) & 0xFFFF);
56 void
57 gsrand(unsigned int seed)
59 next = seed;
64 void
65 TimeCalc()
67 /* adjust number of moves remaining in gamein games */
68 int increment = 0;
69 int topsum = 0;
70 int tcompsum = 0;
71 int me, him;
72 int i;
74 /* Don't do anything until you have enough numbers. */
75 if (GameCnt < (MINGAMEIN * 2))
76 return;
78 /* Calculate average time in sec for last MINGAMEIN moves. */
79 for (i = 0; i < MINGAMEIN; i++)
81 tcompsum += timecomp[i];
82 topsum += timeopp[i];
85 topsum /= (100 * MINGAMEIN);
86 tcompsum /= (100 * MINGAMEIN);
88 /* If I have less time than opponent add another move. */
89 me = TimeControl.clock[computer] / 100;
90 him = TimeControl.clock[opponent] / 100;
92 if (me < him)
93 increment += 2;
95 if (((him - me) > 60) || ((me < him) && (me < 120)))
96 increment++;
98 /* If I am losing more time with each move add another. */
99 /* If (!((me - him) > 60) && tcompsum > topsum) increment++; */
101 if (tcompsum > topsum)
103 increment += 2;
105 else if ((TimeControl.moves[computer] < MINMOVES) && !increment)
107 /* ... but don't let moves go below MINMOVES. */
108 increment++;
110 else if ((me > him) && (tcompsum < topsum))
112 /* If I am doing really well use more time per move. */
113 increment = -1;
116 /* If not fischer clock be careful about time. */
117 /* CHECKME: what's a fischer clock? */
119 if ((TCadd == 0) && (increment > 0))
120 increment += 2;
122 if ((me == 0) && (increment > 0))
123 increment += 2;
125 TimeControl.moves[computer] += increment;
131 * Set ResponseTime, TCcount, and TCleft.
134 void SetResponseTime(short side)
136 bool DetermineTCcount = true;
138 if (TCflag)
140 TCcount = 0;
142 if (TimeControl.moves[side] < 1)
143 TimeControl.moves[side] = 1;
145 /* special case time per move specified */
146 if (flag.onemove)
148 ResponseTime = TimeControl.clock[side] - 100;
149 TCleft = 0;
151 else
153 /* calculate avg time per move remaining */
154 if (TimeControl.clock[side] <= 0)
156 ResponseTime = 0;
157 TCleft = (long)MINRESPONSETIME / MAXTCCOUNTX;
159 else
161 short rtf = in_opening_stage ? 8 : 2;
162 short tcq = in_opening_stage ? 2 : 4;
164 TimeControl.clock[side] += TCadd;
165 ResponseTime = (TimeControl.clock[side])
166 / (((TimeControl.moves[side]) * rtf) + 1);
167 TCleft = (long)ResponseTime / tcq;
168 ResponseTime += TCadd / 2;
171 if (TimeControl.moves[side] < 5)
173 TCcount = MAXTCCOUNTX - 6 - TimeControl.moves[side];
175 if (TCcount < 0)
176 TCcount = 0;
178 DetermineTCcount = false;
182 if (ResponseTime < MINRESPONSETIME)
184 ResponseTime = MINRESPONSETIME;
185 TCcount = MAXTCCOUNTX - 10;
187 if (TCcount < 0)
188 TCcount = 0;
190 DetermineTCcount = false;
193 if (!hard_time_limit && (ResponseTime < 2 * MINRESPONSETIME))
195 TCcount = MAXTCCOUNTX - 10;
197 if (TCcount < 0)
198 TCcount = 0;
200 DetermineTCcount = false;
203 else
205 TCleft = 0;
206 ResponseTime = MaxResponseTime;
207 ElapsedTime(COMPUTE_AND_INIT_MODE);
210 if (DetermineTCcount)
212 if (TCleft )
214 int AllowedCounts
215 = ((int)((TimeControl.clock[side] - ResponseTime)) / 2)
216 / TCleft;
218 if (AllowedCounts <= 0)
219 TCcount = MAXTCCOUNTX;
220 else if (AllowedCounts > MAXTCCOUNTX)
221 TCcount = 0;
222 else
223 TCcount = MAXTCCOUNTX - AllowedCounts;
225 else
227 TCcount = MAXTCCOUNTX;
231 if (ResponseTime < MINRESPONSETIME)
232 ResponseTime = MINRESPONSETIME;
234 assert(TCcount <= MAXTCCOUNTX);
239 void
240 CheckForTimeout(int score, int globalscore, int Jscore, int zwndw)
242 if (flag.musttimeout || (Sdepth >= MaxSearchDepth))
243 flag.timeout = true;
245 else if (TCflag && (Sdepth > (MINDEPTH - 1)) && (TCcount < MAXTCCOUNTR))
247 if (killr0[1] != PrVar[1] /* || Killr0[2] != PrVar[2] */)
249 TCcount++;
250 ExtraTime += TCleft;
253 if ((TCcount < MAXTCCOUNTR)
254 && (abs(score - globalscore) / Sdepth) > ZDELTA)
256 TCcount++;
257 ExtraTime += TCleft;
261 if ((score > (Jscore - zwndw)) && (score > (Tree[1].score + 250)))
262 ExtraTime = 0;
264 ElapsedTime(COMPUTE_MODE);
266 if (root->flags & exact)
267 flag.timeout = true;
268 /*else if (Tree[1].score < -SCORE_LIMIT) flag.timeout = true;
270 #if defined OLDTIME || !defined HAVE_GETTIMEOFDAY
271 else if (!(Sdepth < MINDEPTH)
272 && TCflag
273 && ((4 * et) > (2*ResponseTime + ExtraTime)))
274 flag.timeout = true;
275 #else
276 else if (!(Sdepth < MINDEPTH)
277 && TCflag
278 && ((int)(1.93913099l * (pow((double)et, 1.12446928l)))
279 > (ResponseTime + ExtraTime)))
280 flag.timeout = true;
281 #endif
283 if (flag.timeout)
284 dsp->ShowMessage("timeout");
289 * Determine the time that has passed since the search was started. If the
290 * elapsed time exceeds the target(ResponseTime + ExtraTime) then set timeout
291 * to true which will terminate the search.
292 * iop = COMPUTE_MODE calculate et, bump ETnodes
293 * iop = COMPUTE_AND_INIT_MODE calculate et, set timeout if time exceeded,
294 * set reference time
296 void
297 ElapsedTime(ElapsedTime_mode iop)
299 long current_time;
300 #ifdef HAVE_GETTIMEOFDAY
301 struct timeval tv;
302 #endif
304 dsp->PollForInput();
306 #ifdef HAVE_GETTIMEOFDAY
307 gettimeofday(&tv, NULL);
308 current_time = tv.tv_sec*100 + (tv.tv_usec/10000);
309 #else
310 et = ((current_time = time((long *) 0)) - time0) * 100;
311 #endif
313 #ifdef INTERRUPT_TEST
314 if (iop == INIT_INTERRUPT_MODE)
316 itime0 = current_time;
318 else if (iop == COMPUTE_INTERRUPT_MODE)
320 it = current_time - itime0;
322 else
323 #endif
325 #ifdef HAVE_GETTIMEOFDAY
326 et = current_time - time0;
327 #endif
328 ETnodes = NodeCnt + znodes;
330 if (et < 0)
332 #ifdef INTERRUPT_TEST
333 printf("elapsed time %ld not positive\n", et);
334 #endif
335 et = 0;
338 if (iop == COMPUTE_AND_INIT_MODE)
340 if ((et > (ResponseTime + ExtraTime)) && (Sdepth > MINDEPTH))
341 flag.timeout = true;
343 time0 = current_time;
346 #ifdef QUIETBACKGROUND
347 if (!background)
348 #endif
349 dsp->UpdateClocks();
354 void
355 SetTimeControl(void)
357 if (TCflag)
359 TimeControl.moves[black] = TimeControl.moves[white] = TCmoves;
360 TimeControl.clock[black] += 6000L * TCminutes + TCseconds * 100;
361 TimeControl.clock[white] += 6000L * TCminutes + TCseconds * 100;
363 else
365 TimeControl.moves[black] = TimeControl.moves[white] = 0;
366 TimeControl.clock[black] = TimeControl.clock[white] = 0;
369 flag.onemove = (TCmoves == 1);
370 et = 0;
371 ElapsedTime(COMPUTE_AND_INIT_MODE);