4 * ----------------------------------------------------------------------
5 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
8 * GNU SHOGI is based on GNU CHESS
10 * Copyright (c) 1988, 1989, 1990 John Stanback
11 * Copyright (c) 1992 Free Software Foundation
13 * This file is part of GNU SHOGI.
15 * GNU Shogi is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 3 of the License,
18 * or (at your option) any later version.
20 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * You should have received a copy of the GNU General Public License along
26 * with GNU Shogi; see the file COPYING. If not, see
27 * <http://www.gnu.org/licenses/>.
28 * ----------------------------------------------------------------------
36 #define ALTERNATIVE_TC
40 * In a networked enviroment gnushogi might be compiled on different hosts
41 * with different random number generators; that is not acceptable if they
42 * are going to share the same transposition table.
45 static unsigned long next = 1;
52 return ((unsigned int) (next >> 16) & 0xFFFF);
58 gsrand(unsigned int seed)
68 /* adjust number of moves remaining in gamein games */
75 /* Don't do anything until you have enough numbers. */
76 if (GameCnt < (MINGAMEIN * 2))
79 /* Calculate average time in sec for last MINGAMEIN moves. */
80 for (i = 0; i < MINGAMEIN; i++)
82 tcompsum += timecomp[i];
86 topsum /= (100 * MINGAMEIN);
87 tcompsum /= (100 * MINGAMEIN);
89 /* If I have less time than opponent add another move. */
90 me = TimeControl.clock[computer] / 100;
91 him = TimeControl.clock[opponent] / 100;
96 if (((him - me) > 60) || ((me < him) && (me < 120)))
99 /* If I am losing more time with each move add another. */
100 /* If (!((me - him) > 60) && tcompsum > topsum) increment++; */
102 if (tcompsum > topsum)
106 else if ((TimeControl.moves[computer] < MINMOVES) && !increment)
108 /* ... but don't let moves go below MINMOVES. */
111 else if ((me > him) && (tcompsum < topsum))
113 /* If I am doing really well use more time per move. */
117 /* If not fischer clock be careful about time. */
118 /* CHECKME: what's a fischer clock? */
120 if ((TCadd == 0) && (increment > 0))
123 if ((me == 0) && (increment > 0))
126 TimeControl.moves[computer] += increment;
132 * Set ResponseTime, TCcount, and TCleft.
135 void SetResponseTime(short side)
137 #ifdef ALTERNATIVE_TC
138 int DetermineTCcount = true;
144 if (TimeControl.moves[side] < 1)
145 TimeControl.moves[side] = 1;
147 /* special case time per move specified */
150 ResponseTime = TimeControl.clock[side] - 100;
155 /* calculate avg time per move remaining */
156 if (TimeControl.clock[side] <= 0)
159 TCleft = (long)MINRESPONSETIME / MAXTCCOUNTX;
163 short rtf = in_opening_stage ? 8 : 2;
164 short tcq = in_opening_stage ? 2 : 4;
166 TimeControl.clock[side] += TCadd;
167 ResponseTime = (TimeControl.clock[side])
168 / (((TimeControl.moves[side]) * rtf) + 1);
169 TCleft = (long)ResponseTime / tcq;
170 ResponseTime += TCadd / 2;
173 if (TimeControl.moves[side] < 5)
175 TCcount = MAXTCCOUNTX - 10;
180 DetermineTCcount = false;
184 if (ResponseTime < MINRESPONSETIME)
186 ResponseTime = MINRESPONSETIME;
187 TCcount = MAXTCCOUNTX - 10;
192 DetermineTCcount = false;
195 if (!hard_time_limit && (ResponseTime < 2 * MINRESPONSETIME))
197 TCcount = MAXTCCOUNTX - 10;
202 DetermineTCcount = false;
208 ResponseTime = MaxResponseTime;
209 ElapsedTime(COMPUTE_AND_INIT_MODE);
212 if (DetermineTCcount)
217 = ((int)((TimeControl.clock[side] - ResponseTime)) / 2)
220 if (AllowedCounts <= 0)
221 TCcount = MAXTCCOUNTX;
222 else if (AllowedCounts > MAXTCCOUNTX)
225 TCcount = MAXTCCOUNTX - AllowedCounts;
229 TCcount = MAXTCCOUNTX;
233 if (ResponseTime < MINRESPONSETIME)
234 ResponseTime = MINRESPONSETIME;
242 if (TimeControl.moves[side] < 1)
243 TimeControl.moves[side] = 1;
245 /* special case time per move specified */
248 ResponseTime = TimeControl.clock[side] - 100;
253 /* calculate avg time per move remaining */
254 TimeControl.clock[side] += TCadd;
256 ResponseTime = (TimeControl.clock[side])
257 / (((TimeControl.moves[side]) * 2) + 1);
258 TCleft = (int) ResponseTime / 3;
259 ResponseTime += TCadd / 2;
261 if (TimeControl.moves[side] < 5)
262 TCcount = MAXTCCOUNTX - 10;
265 if (ResponseTime < 101)
268 TCcount = MAXTCCOUNTX - 10;
270 else if (ResponseTime < 200)
272 TCcount = MAXTCCOUNTX - 10;
277 ResponseTime = MaxResponseTime;
279 ElapsedTime(COMPUTE_AND_INIT_MODE);
284 TCcount = ((int)((TimeControl.clock[side] - ResponseTime)) / 2)
287 if (TCcount > MAXTCCOUNTX)
290 TCcount = MAXTCCOUNTX - TCcount;
294 TCcount = MAXTCCOUNTX;
298 assert(TCcount <= MAXTCCOUNTX);
304 CheckForTimeout(int score, int globalscore, int Jscore, int zwndw)
306 if (flag.musttimeout || (Sdepth >= MaxSearchDepth))
309 else if (TCflag && (Sdepth > (MINDEPTH - 1)) && (TCcount < MAXTCCOUNTR))
311 if (killr0[1] != PrVar[1] /* || Killr0[2] != PrVar[2] */)
317 if ((TCcount < MAXTCCOUNTR)
318 && (abs(score - globalscore) / Sdepth) > ZDELTA)
325 if ((score > (Jscore - zwndw)) && (score > (Tree[1].score + 250)))
328 ElapsedTime(COMPUTE_MODE);
330 if (root->flags & exact)
332 /*else if (Tree[1].score < -SCORE_LIMIT) flag.timeout = true;
334 #if defined OLDTIME || !defined HAVE_GETTIMEOFDAY
335 else if (!(Sdepth < MINDEPTH)
337 && ((4 * et) > (2*ResponseTime + ExtraTime)))
340 else if (!(Sdepth < MINDEPTH)
342 && ((int)(1.93913099l * (pow((double)et, 1.12446928l)))
343 > (ResponseTime + ExtraTime)))
348 ShowMessage("timeout");