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
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 * ----------------------------------------------------------------------
37 #define ALTERNATIVE_TC
41 * In a networked enviroment gnushogi might be compiled on different hosts
42 * with different random number generators; that is not acceptable if they
43 * are going to share the same transposition table.
46 static unsigned long next
= 1;
53 return ((unsigned int) (next
>> 16) & 0xFFFF);
59 gsrand(unsigned int seed
)
69 /* adjust number of moves remaining in gamein games */
76 /* Don't do anything until you have enough numbers. */
77 if (GameCnt
< (MINGAMEIN
* 2))
80 /* Calculate average time in sec for last MINGAMEIN moves. */
81 for (i
= 0; i
< MINGAMEIN
; i
++)
83 tcompsum
+= timecomp
[i
];
87 topsum
/= (100 * MINGAMEIN
);
88 tcompsum
/= (100 * MINGAMEIN
);
90 /* If I have less time than opponent add another move. */
91 me
= TimeControl
.clock
[computer
] / 100;
92 him
= TimeControl
.clock
[opponent
] / 100;
97 if (((him
- me
) > 60) || ((me
< him
) && (me
< 120)))
100 /* If I am losing more time with each move add another. */
101 /* If (!((me - him) > 60) && tcompsum > topsum) increment++; */
103 if (tcompsum
> topsum
)
107 else if ((TimeControl
.moves
[computer
] < MINMOVES
) && !increment
)
109 /* ... but don't let moves go below MINMOVES. */
112 else if ((me
> him
) && (tcompsum
< topsum
))
114 /* If I am doing really well use more time per move. */
118 /* If not fischer clock be careful about time. */
119 /* CHECKME: what's a fischer clock? */
121 if ((TCadd
== 0) && (increment
> 0))
124 if ((me
== 0) && (increment
> 0))
127 TimeControl
.moves
[computer
] += increment
;
133 * Set ResponseTime, TCcount, and TCleft.
136 void SetResponseTime(short side
)
138 #ifdef ALTERNATIVE_TC
139 int DetermineTCcount
= true;
145 if (TimeControl
.moves
[side
] < 1)
146 TimeControl
.moves
[side
] = 1;
148 /* special case time per move specified */
151 ResponseTime
= TimeControl
.clock
[side
] - 100;
156 /* calculate avg time per move remaining */
157 if (TimeControl
.clock
[side
] <= 0)
160 TCleft
= (long)MINRESPONSETIME
/ MAXTCCOUNTX
;
164 short rtf
= in_opening_stage
? 8 : 2;
165 short tcq
= in_opening_stage
? 2 : 4;
167 TimeControl
.clock
[side
] += TCadd
;
168 ResponseTime
= (TimeControl
.clock
[side
])
169 / (((TimeControl
.moves
[side
]) * rtf
) + 1);
170 TCleft
= (long)ResponseTime
/ tcq
;
171 ResponseTime
+= TCadd
/ 2;
174 if (TimeControl
.moves
[side
] < 5)
176 TCcount
= MAXTCCOUNTX
- 10;
181 DetermineTCcount
= false;
185 if (ResponseTime
< MINRESPONSETIME
)
187 ResponseTime
= MINRESPONSETIME
;
188 TCcount
= MAXTCCOUNTX
- 10;
193 DetermineTCcount
= false;
196 if (!hard_time_limit
&& (ResponseTime
< 2 * MINRESPONSETIME
))
198 TCcount
= MAXTCCOUNTX
- 10;
203 DetermineTCcount
= false;
209 ResponseTime
= MaxResponseTime
;
210 ElapsedTime(COMPUTE_AND_INIT_MODE
);
213 if (DetermineTCcount
)
218 = ((int)((TimeControl
.clock
[side
] - ResponseTime
)) / 2)
221 if (AllowedCounts
<= 0)
222 TCcount
= MAXTCCOUNTX
;
223 else if (AllowedCounts
> MAXTCCOUNTX
)
226 TCcount
= MAXTCCOUNTX
- AllowedCounts
;
230 TCcount
= MAXTCCOUNTX
;
234 if (ResponseTime
< MINRESPONSETIME
)
235 ResponseTime
= MINRESPONSETIME
;
243 if (TimeControl
.moves
[side
] < 1)
244 TimeControl
.moves
[side
] = 1;
246 /* special case time per move specified */
249 ResponseTime
= TimeControl
.clock
[side
] - 100;
254 /* calculate avg time per move remaining */
255 TimeControl
.clock
[side
] += TCadd
;
257 ResponseTime
= (TimeControl
.clock
[side
])
258 / (((TimeControl
.moves
[side
]) * 2) + 1);
259 TCleft
= (int) ResponseTime
/ 3;
260 ResponseTime
+= TCadd
/ 2;
262 if (TimeControl
.moves
[side
] < 5)
263 TCcount
= MAXTCCOUNTX
- 10;
266 if (ResponseTime
< 101)
269 TCcount
= MAXTCCOUNTX
- 10;
271 else if (ResponseTime
< 200)
273 TCcount
= MAXTCCOUNTX
- 10;
278 ResponseTime
= MaxResponseTime
;
280 ElapsedTime(COMPUTE_AND_INIT_MODE
);
285 TCcount
= ((int)((TimeControl
.clock
[side
] - ResponseTime
)) / 2)
288 if (TCcount
> MAXTCCOUNTX
)
291 TCcount
= MAXTCCOUNTX
- TCcount
;
295 TCcount
= MAXTCCOUNTX
;
299 assert(TCcount
<= MAXTCCOUNTX
);
305 CheckForTimeout(int score
, int globalscore
, int Jscore
, int zwndw
)
307 if (flag
.musttimeout
|| (Sdepth
>= MaxSearchDepth
))
310 else if (TCflag
&& (Sdepth
> (MINDEPTH
- 1)) && (TCcount
< MAXTCCOUNTR
))
312 if (killr0
[1] != PrVar
[1] /* || Killr0[2] != PrVar[2] */)
318 if ((TCcount
< MAXTCCOUNTR
)
319 && (abs(score
- globalscore
) / Sdepth
) > ZDELTA
)
326 if ((score
> (Jscore
- zwndw
)) && (score
> (Tree
[1].score
+ 250)))
329 ElapsedTime(COMPUTE_MODE
);
331 if (root
->flags
& exact
)
333 /*else if (Tree[1].score < -SCORE_LIMIT) flag.timeout = true;
335 #if defined OLDTIME || !defined HAVE_GETTIMEOFDAY
336 else if (!(Sdepth
< MINDEPTH
)
338 && ((4 * et
) > (2*ResponseTime
+ ExtraTime
)))
341 else if (!(Sdepth
< MINDEPTH
)
343 && ((int)(1.93913099l * (pow((double)et
, 1.12446928l)))
344 > (ResponseTime
+ ExtraTime
)))
349 dsp
->ShowMessage("timeout");
354 * Determine the time that has passed since the search was started. If the
355 * elapsed time exceeds the target(ResponseTime + ExtraTime) then set timeout
356 * to true which will terminate the search.
357 * iop = COMPUTE_MODE calculate et, bump ETnodes
358 * iop = COMPUTE_AND_INIT_MODE calculate et, set timeout if time exceeded,
362 ElapsedTime(ElapsedTime_mode iop
)
365 #ifdef HAVE_GETTIMEOFDAY
371 #ifdef HAVE_GETTIMEOFDAY
372 gettimeofday(&tv
, NULL
);
373 current_time
= tv
.tv_sec
*100 + (tv
.tv_usec
/10000);
375 et
= ((current_time
= time((long *) 0)) - time0
) * 100;
378 #ifdef INTERRUPT_TEST
379 if (iop
== INIT_INTERRUPT_MODE
)
381 itime0
= current_time
;
383 else if (iop
== COMPUTE_INTERRUPT_MODE
)
385 it
= current_time
- itime0
;
390 #ifdef HAVE_GETTIMEOFDAY
391 et
= current_time
- time0
;
393 ETnodes
= NodeCnt
+ znodes
;
397 #ifdef INTERRUPT_TEST
398 printf("elapsed time %ld not positive\n", et
);
403 if (iop
== COMPUTE_AND_INIT_MODE
)
405 if ((et
> (ResponseTime
+ ExtraTime
)) && (Sdepth
> MINDEPTH
))
408 time0
= current_time
;
411 #ifdef QUIETBACKGROUND
424 TimeControl
.moves
[black
] = TimeControl
.moves
[white
] = TCmoves
;
425 TimeControl
.clock
[black
] += 6000L * TCminutes
+ TCseconds
* 100;
426 TimeControl
.clock
[white
] += 6000L * TCminutes
+ TCseconds
* 100;
430 TimeControl
.moves
[black
] = TimeControl
.moves
[white
] = 0;
431 TimeControl
.clock
[black
] = TimeControl
.clock
[white
] = 0;
434 flag
.onemove
= (TCmoves
== 1);
436 ElapsedTime(COMPUTE_AND_INIT_MODE
);