Initial commit based on GNU Shogi 1.2 patchlevel 3.
[gnushogi.git] / src / tcontrl.c
blob7b4db9468d0c29abe121b1edd126a4e56d89d411
1 /*
2 * tcontrl.c - C source for GNU SHOGI
4 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * GNU SHOGI is based on GNU CHESS
8 * Copyright (c) 1988,1989,1990 John Stanback
9 * Copyright (c) 1992 Free Software Foundation
11 * This file is part of GNU SHOGI.
13 * GNU Shogi is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 1, or (at your option)
16 * any later version.
18 * GNU Shogi is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with GNU Shogi; see the file COPYING. If not, write to
25 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include "gnushogi.h"
30 #ifdef DEBUG
31 #include <assert.h>
32 #else
33 #include <assert.h>
34 #endif
36 #define ALTERNATIVE_TC
38 #if !defined OLDTIME && defined HASGETTIMEOFDAY
39 double pow();
40 #endif
44 * In a networked enviroment gnuchess might be compiled on different hosts
45 * with different random number generators, that is not acceptable if they
46 * are going to share the same transposition table.
49 static unsigned long int next = 1;
51 unsigned int
52 urand (void)
54 next *= 1103515245;
55 next += 12345;
56 return ((unsigned int) (next >> 16) & 0xFFFF);
59 void
60 gsrand (unsigned int seed)
62 next = seed;
67 void
68 TimeCalc ()
70 /* adjust number of moves remaining in gamein games */
71 int increment = 0;
72 int topsum = 0;
73 int tcompsum = 0;
74 int me,him;
75 int i;
76 /* dont do anything til you have enough numbers */
77 if (GameCnt < (MINGAMEIN * 2)) 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];
84 topsum /= (100 * MINGAMEIN);
85 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;
89 if(me < him) increment += 2;
90 if((him - me) > 60 || (me<him && me < 120))increment++;
91 /* if I am losing more time with each move add another */
92 /*if ( !((me - him) > 60) && tcompsum > topsum) increment++;*/
93 if ( tcompsum > topsum) increment +=2;
94 /* but dont let moves go below MINMOVES */
95 else if (TimeControl.moves[computer] < MINMOVES && !increment) increment++;
96 /* if I am doing really well use more time per move */
97 else if (me > him && tcompsum < topsum) increment = -1;
98 /* if not fischer clock be careful about time */
99 if(TCadd == 0 && increment >0)increment += 2;
100 if(me == 0 && increment >0)increment += 2;
101 TimeControl.moves[computer] += increment;
108 * Set ResponseTime, TCcount, and TCleft.
111 void SetResponseTime (short int side)
114 #ifdef ALTERNATIVE_TC
116 int DetermineTCcount = true;
118 if (TCflag)
120 TCcount = 0;
121 if (TimeControl.moves[side] < 1)
122 TimeControl.moves[side] = 1;
123 /* special case time per move specified */
124 if (flag.onemove)
126 ResponseTime = TimeControl.clock[side] - 100;
127 TCleft = 0;
129 else
131 /* calculate avg time per move remaining */
132 if ( TimeControl.clock[side] <= 0 )
134 ResponseTime = 0;
135 TCleft = (long)MINRESPONSETIME / MAXTCCOUNTX;
137 else
139 #ifdef DEBUG
140 char buffer[80];
141 #endif
142 short rtf = in_opening_stage ? 8 : 2;
143 short tcq = in_opening_stage ? 2 : 4;
144 TimeControl.clock[side] += TCadd;
145 ResponseTime =
146 (TimeControl.clock[side]) /
147 (((TimeControl.moves[side]) * rtf) + 1);
148 TCleft = (long)ResponseTime / tcq;
149 ResponseTime += TCadd/2;
150 #ifdef DEBUG
151 sprintf(buffer,"rtf=%d tcq=%d rt=%ld tl=%ld",
152 rtf,tcq,ResponseTime,TCleft);
153 ShowMessage(buffer);
154 #endif
156 if (TimeControl.moves[side] < 5)
158 TCcount = MAXTCCOUNTX - 10;
159 if ( TCcount < 0 ) TCcount = 0;
160 DetermineTCcount = false;
163 if (ResponseTime < MINRESPONSETIME)
165 ResponseTime = MINRESPONSETIME;
166 TCcount = MAXTCCOUNTX - 10;
167 if ( TCcount < 0 ) TCcount = 0;
168 DetermineTCcount = false;
170 #ifndef HARDTIMELIMIT
171 else if (ResponseTime < 2*MINRESPONSETIME)
173 TCcount = MAXTCCOUNTX - 10;
174 if ( TCcount < 0 ) TCcount = 0;
175 DetermineTCcount = false;
177 #endif
179 else
181 TCleft = 0;
182 ResponseTime = MaxResponseTime;
183 ElapsedTime(COMPUTE_AND_INIT_MODE);
186 if ( DetermineTCcount )
187 if ( TCleft )
189 int AllowedCounts = ((int)((TimeControl.clock[side] - ResponseTime)) / 2) / TCleft;
191 if ( AllowedCounts <= 0 )
192 TCcount = MAXTCCOUNTX;
193 else if (AllowedCounts > MAXTCCOUNTX)
194 TCcount = 0;
195 else
196 TCcount = MAXTCCOUNTX - AllowedCounts;
198 else
200 TCcount = MAXTCCOUNTX;
203 if ( ResponseTime < MINRESPONSETIME )
204 ResponseTime = MINRESPONSETIME;
206 #else
208 if (TCflag)
210 TCcount = 0;
211 if (TimeControl.moves[side] < 1)
212 TimeControl.moves[side] = 1;
213 /* special case time per move specified */
214 if (flag.onemove)
216 ResponseTime = TimeControl.clock[side] - 100;
217 TCleft = 0;
219 else
221 /* calculate avg time per move remaining */
222 TimeControl.clock[side] += TCadd;
224 ResponseTime = (TimeControl.clock[side]) / (((TimeControl.moves[side]) * 2) + 1);
225 TCleft = (int) ResponseTime / 3;
226 ResponseTime += TCadd / 2;
227 if (TimeControl.moves[side] < 5)
228 TCcount = MAXTCCOUNTX - 10;
230 if (ResponseTime < 101)
232 ResponseTime = 100;
233 TCcount = MAXTCCOUNTX - 10;
235 else if (ResponseTime < 200)
237 TCcount = MAXTCCOUNTX - 10;
240 else
242 ResponseTime = MaxResponseTime;
243 TCleft = 0;
244 ElapsedTime (COMPUTE_AND_INIT_MODE);
246 if (TCleft)
248 TCcount = ((int) ((TimeControl.clock[side] - ResponseTime)) / 2) / TCleft;
249 if (TCcount > MAXTCCOUNTX)
250 TCcount = 0;
251 else
252 TCcount = MAXTCCOUNTX - TCcount;
254 else
255 TCcount = MAXTCCOUNTX;
257 #endif
259 assert(TCcount <= MAXTCCOUNTX);
264 void CheckForTimeout (int score, int globalscore, int Jscore, int zwndw)
266 if (flag.musttimeout || Sdepth >= MaxSearchDepth)
267 flag.timeout = true;
269 else if (TCflag && (Sdepth > (MINDEPTH - 1)) && (TCcount < MAXTCCOUNTR))
271 if (killr0[1] != PrVar[1] /* || Killr0[2] != PrVar[2] */ )
273 TCcount++;
274 ExtraTime += TCleft;
276 if (TCcount < MAXTCCOUNTR && (abs (score - globalscore) / Sdepth) > ZDELTA)
278 TCcount++;
279 ExtraTime += TCleft;
282 if (score > (Jscore - zwndw) && score > (Tree[1].score + 250))
283 ExtraTime = 0;
284 ElapsedTime(COMPUTE_MODE);
285 if (root->flags & exact)
286 flag.timeout = true;
287 /*else if (Tree[1].score < -SCORE_LIMIT) flag.timeout = true;*/
288 #if defined OLDTIME || !defined HASGETTIMEOFDAY
289 else if (!(Sdepth < MINDEPTH) && TCflag && ((4 * et) > (2*ResponseTime + ExtraTime)))
290 flag.timeout = true;
291 #else
292 else if (!(Sdepth < MINDEPTH) && TCflag &&
293 ((int)(1.93913099l * (pow((double)et,1.12446928l))) > (ResponseTime + ExtraTime)))
294 flag.timeout = true;
295 #endif
296 #if !defined BAREBONES
297 if ( flag.timeout )
298 ShowMessage("timeout");
299 #endif