29 |
#include <string.h> |
#include <string.h> |
30 |
#include "common.h" |
#include "common.h" |
31 |
|
|
|
#define R 2*DEPTH |
|
32 |
#define TIMECHECK 1023 |
#define TIMECHECK 1023 |
33 |
#define HISTSCORE(d) ((d)*(d)) |
#define HISTSCORE(d) ((d)*(d)) |
34 |
|
|
45 |
return; |
return; |
46 |
} |
} |
47 |
SANMove (p->move, ply); |
SANMove (p->move, ply); |
48 |
printf ("\r%2d. %2d/%2d%10s ", Idepth/DEPTH, |
printf ("\r%2d. %2d/%2d%10s ", Idepth, |
49 |
(int) (p-TreePtr[ply]+1), (int) (TreePtr[ply+1]-TreePtr[ply]), SANmv); |
(int) (p-TreePtr[ply]+1), (int) (TreePtr[ply+1]-TreePtr[ply]), SANmv); |
50 |
fflush (stdout); |
fflush (stdout); |
51 |
} |
} |
75 |
KingThrt[white][ply] = MateScan (white); |
KingThrt[white][ply] = MateScan (white); |
76 |
KingThrt[black][ply] = MateScan (black); |
KingThrt[black][ply] = MateScan (black); |
77 |
InChk[ply] = SqAtakd (board.king[side], xside); |
InChk[ply] = SqAtakd (board.king[side], xside); |
78 |
if (InChk[ply] && ChkCnt[ply] < 3*Idepth/DEPTH) |
if (InChk[ply] && ChkCnt[ply] < 3*Idepth) |
79 |
{ |
{ |
80 |
ChkExtCnt++; |
ChkExtCnt++; |
81 |
ChkCnt[ply+1]++; |
ChkCnt[ply+1]++; |
82 |
depth += DEPTH; |
depth += 1; |
83 |
} |
} |
84 |
best = -INFINITY; |
best = -INFINITY; |
85 |
savealpha = alpha; |
savealpha = alpha; |
96 |
/* If first move, search against full alpha-beta window */ |
/* If first move, search against full alpha-beta window */ |
97 |
if (p == TreePtr[1]) |
if (p == TreePtr[1]) |
98 |
{ |
{ |
99 |
score = -Search (2, depth-DEPTH, -beta, -alpha, nodetype); |
score = -Search (2, depth-1, -beta, -alpha, nodetype); |
100 |
/* |
/* |
101 |
The following occurs when we are re-searching a fail high move |
The following occurs when we are re-searching a fail high move |
102 |
and now it has fail low. This can be disastrous, so immediately |
and now it has fail low. This can be disastrous, so immediately |
105 |
if (beta == INFINITY && score <= alpha) |
if (beta == INFINITY && score <= alpha) |
106 |
{ |
{ |
107 |
alpha = -INFINITY; |
alpha = -INFINITY; |
108 |
score = -Search (2, depth-DEPTH, -beta, -alpha, nodetype); |
score = -Search (2, depth-1, -beta, -alpha, nodetype); |
109 |
} |
} |
110 |
} |
} |
111 |
|
|
114 |
{ |
{ |
115 |
nodetype = CUT; |
nodetype = CUT; |
116 |
alpha = MAX (best, alpha); |
alpha = MAX (best, alpha); |
117 |
score = -Search (2, depth-DEPTH, -alpha-1, -alpha, nodetype); |
score = -Search (2, depth-1, -alpha-1, -alpha, nodetype); |
118 |
if (score > best) |
if (score > best) |
119 |
{ |
{ |
120 |
if (alpha < score && score < beta) |
if (alpha < score && score < beta) |
121 |
{ |
{ |
122 |
nodetype = PV; |
nodetype = PV; |
123 |
score = -Search (2, depth-DEPTH, -beta, -score, nodetype); |
score = -Search (2, depth-1, -beta, -score, nodetype); |
124 |
} |
} |
125 |
} |
} |
126 |
} |
} |
182 |
|
|
183 |
/* Update history */ |
/* Update history */ |
184 |
if (best > savealpha) |
if (best > savealpha) |
185 |
history[side][pbest->move & 0x0FFF] += HISTSCORE(depth/DEPTH); |
history[side][pbest->move & 0x0FFF] += HISTSCORE(depth); |
186 |
|
|
187 |
rootscore = best; |
rootscore = best; |
188 |
return (best); |
return (best); |
240 |
return (-MATE+ply-2); |
return (-MATE+ply-2); |
241 |
if (TreePtr[ply]+1 == TreePtr[ply+1]) |
if (TreePtr[ply]+1 == TreePtr[ply+1]) |
242 |
{ |
{ |
243 |
depth += DEPTH; |
depth += 1; |
244 |
extend = true; |
extend = true; |
245 |
OneRepCnt++; |
OneRepCnt++; |
246 |
} |
} |
261 |
ThrtCnt[ply+1] = ThrtCnt[ply]; |
ThrtCnt[ply+1] = ThrtCnt[ply]; |
262 |
KingThrt[white][ply] = MateScan (white); |
KingThrt[white][ply] = MateScan (white); |
263 |
KingThrt[black][ply] = MateScan (black); |
KingThrt[black][ply] = MateScan (black); |
264 |
if (InChk[ply] && /* ChkCnt[ply] < Idepth-1*/ ply <= 2*Idepth/DEPTH) |
if (InChk[ply] && /* ChkCnt[ply] < Idepth-1*/ ply <= 2*Idepth) |
265 |
{ |
{ |
266 |
ChkExtCnt++; |
ChkExtCnt++; |
267 |
ChkCnt[ply+1]++; |
ChkCnt[ply+1]++; |
268 |
depth += DEPTH; |
depth += 1; |
269 |
extend = true; |
extend = true; |
270 |
} |
} |
271 |
else if (!KingThrt[side][ply-1] && KingThrt[side][ply] && ply <= 2*Idepth/DEPTH) |
else if (!KingThrt[side][ply-1] && KingThrt[side][ply] && ply <= 2*Idepth) |
272 |
{ |
{ |
273 |
KingExtCnt++; |
KingExtCnt++; |
274 |
extend = true; |
extend = true; |
275 |
depth += DEPTH; |
depth += 1; |
276 |
extend = true; |
extend = true; |
277 |
donull = false; |
donull = false; |
278 |
} |
} |
280 |
else if (g0 & PROMOTION) |
else if (g0 & PROMOTION) |
281 |
{ |
{ |
282 |
PawnExtCnt++; |
PawnExtCnt++; |
283 |
depth += DEPTH; /* Not reached, but why?! */ |
depth += 1; /* Not reached, but why?! */ |
284 |
extend = true; |
extend = true; |
285 |
} |
} |
286 |
/* Recapture extension */ |
/* Recapture extension */ |
288 |
board.material[1^computer] == RootMaterial)) |
board.material[1^computer] == RootMaterial)) |
289 |
{ |
{ |
290 |
RcpExtCnt++; |
RcpExtCnt++; |
291 |
depth += DEPTH; |
depth += 1; |
292 |
extend = true; |
extend = true; |
293 |
} |
} |
294 |
/* 6th or 7th rank extension */ |
/* 6th or 7th rank extension */ |
295 |
else if (depth <= DEPTH && cboard[t0] == pawn && (RANK(t0) == rank7[xside] || RANK(t0) == rank6[xside])) |
else if (depth <= 1 && cboard[t0] == pawn && (RANK(t0) == rank7[xside] || RANK(t0) == rank6[xside])) |
296 |
{ |
{ |
297 |
PawnExtCnt++; |
PawnExtCnt++; |
298 |
depth += DEPTH; |
depth += 1; |
299 |
extend = true; |
extend = true; |
300 |
} |
} |
301 |
|
|
309 |
!SqAtakd (t0, xside)) |
!SqAtakd (t0, xside)) |
310 |
{ |
{ |
311 |
HorzExtCnt++; |
HorzExtCnt++; |
312 |
depth += DEPTH; |
depth += 1; |
313 |
extend = true; |
extend = true; |
314 |
} |
} |
315 |
|
|
377 |
*****************************************************************************/ |
*****************************************************************************/ |
378 |
if (ply > 4 && InChk[ply-2] && InChk[ply-4]) |
if (ply > 4 && InChk[ply-2] && InChk[ply-4]) |
379 |
donull = false; |
donull = false; |
380 |
if (flags & USENULL && g0 != NULLMOVE && depth > DEPTH && nodetype != PV && |
if (flags & USENULL && g0 != NULLMOVE && depth > 1 && nodetype != PV && |
381 |
!InChk[ply] && MATERIAL+ValueP > beta && beta > -MATE+ply && donull && |
!InChk[ply] && MATERIAL+ValueP > beta && beta > -MATE+ply && donull && |
382 |
board.pmaterial[side] > ValueB ) |
board.pmaterial[side] > ValueB ) |
383 |
{ |
{ |
384 |
TreePtr[ply+1] = TreePtr[ply]; |
TreePtr[ply+1] = TreePtr[ply]; |
385 |
MakeNullMove (side); |
MakeNullMove (side); |
386 |
nullscore = -Search (ply+1, depth-DEPTH-R, -beta, -beta+1, nodetype); |
nullscore = -Search (ply+1, depth-3, -beta, -beta+1, nodetype); |
387 |
UnmakeNullMove (xside); |
UnmakeNullMove (xside); |
388 |
if (nullscore >= beta) |
if (nullscore >= beta) |
389 |
{ |
{ |
390 |
NullCutCnt++; |
NullCutCnt++; |
391 |
return (nullscore); |
return (nullscore); |
392 |
} |
} |
393 |
if ( depth-DEPTH-R >= 1 && MATERIAL > beta && nullscore <= -MATE+256) |
if ( depth-3 >= 1 && MATERIAL > beta && nullscore <= -MATE+256) |
394 |
{ |
{ |
395 |
depth += DEPTH; |
depth += 1; |
396 |
extend = true; |
extend = true; |
397 |
} |
} |
398 |
} |
} |
416 |
*************************************************************************/ |
*************************************************************************/ |
417 |
fcut = false; |
fcut = false; |
418 |
fdel = MAX (ValueQ, maxposnscore[side]); |
fdel = MAX (ValueQ, maxposnscore[side]); |
419 |
if (!extend && nodetype != PV && depth == 3*DEPTH && FUTSCORE <= alpha) |
if (!extend && nodetype != PV && depth == 3 && FUTSCORE <= alpha) |
420 |
{ |
{ |
421 |
depth = 2*DEPTH; |
depth = 2; |
422 |
RazrCutCnt++; |
RazrCutCnt++; |
423 |
} |
} |
424 |
fdel = MAX (ValueR, maxposnscore[side]); |
fdel = MAX (ValueR, maxposnscore[side]); |
425 |
fcut = (!extend && nodetype != PV && depth == 2*DEPTH && FUTSCORE <= alpha); |
fcut = (!extend && nodetype != PV && depth == 2 && FUTSCORE <= alpha); |
426 |
if (!fcut) |
if (!fcut) |
427 |
{ |
{ |
428 |
fdel = MAX (3*ValueP, maxposnscore[side]); |
fdel = MAX (3*ValueP, maxposnscore[side]); |
429 |
fcut = (nodetype != PV && depth == DEPTH && FUTSCORE <= alpha); |
fcut = (nodetype != PV && depth == 1 && FUTSCORE <= alpha); |
430 |
} |
} |
431 |
|
|
432 |
MakeMove (side, &p->move); |
MakeMove (side, &p->move); |
458 |
if (firstmove) |
if (firstmove) |
459 |
{ |
{ |
460 |
firstmove = false; |
firstmove = false; |
461 |
score = -Search (ply+1, depth-DEPTH, -beta, -alpha, nodetype); |
score = -Search (ply+1, depth-1, -beta, -alpha, nodetype); |
462 |
} |
} |
463 |
|
|
464 |
/* Zero window search for rest of moves */ |
/* Zero window search for rest of moves */ |
498 |
if (nodetype == PV) |
if (nodetype == PV) |
499 |
nodetype = CUT; |
nodetype = CUT; |
500 |
alpha = MAX (best, alpha); /* fail-soft condition */ |
alpha = MAX (best, alpha); /* fail-soft condition */ |
501 |
score = -Search (ply+1, depth-DEPTH, -alpha-1, -alpha, nodetype); |
score = -Search (ply+1, depth-1, -alpha-1, -alpha, nodetype); |
502 |
if (score > best) |
if (score > best) |
503 |
{ |
{ |
504 |
if (savenode == PV) |
if (savenode == PV) |
505 |
nodetype = PV; |
nodetype = PV; |
506 |
if (alpha < score && score < beta) |
if (alpha < score && score < beta) |
507 |
{ |
{ |
508 |
score = -Search (ply+1, depth-DEPTH, -beta, -score, nodetype); |
score = -Search (ply+1, depth-1, -beta, -score, nodetype); |
509 |
} |
} |
510 |
if (nodetype == PV && score <= alpha && |
if (nodetype == PV && score <= alpha && |
511 |
Game[GameCnt+1].move == NULLMOVE) |
Game[GameCnt+1].move == NULLMOVE) |
512 |
{ |
{ |
513 |
score = -Search (ply+1, depth-DEPTH, -alpha, INFINITY, nodetype); |
score = -Search (ply+1, depth-1, -alpha, INFINITY, nodetype); |
514 |
} |
} |
515 |
} |
} |
516 |
} |
} |
578 |
|
|
579 |
/* Update history */ |
/* Update history */ |
580 |
if (best > savealpha) |
if (best > savealpha) |
581 |
history[side][pbest->move & 0x0FFF] += HISTSCORE(depth/DEPTH); |
history[side][pbest->move & 0x0FFF] += HISTSCORE(depth); |
582 |
|
|
583 |
/* Don't store captures as killers as they are tried before killers */ |
/* Don't store captures as killers as they are tried before killers */ |
584 |
if (!(pbest->move & (CAPTURE | PROMOTION)) && best > savealpha) |
if (!(pbest->move & (CAPTURE | PROMOTION)) && best > savealpha) |
613 |
/* printf("NodeCnt = %d\n",NodeCnt); getchar(); */ |
/* printf("NodeCnt = %d\n",NodeCnt); getchar(); */ |
614 |
return; |
return; |
615 |
} |
} |
616 |
if (Idepth == DEPTH && c == '&') |
if (Idepth == 1 && c == '&') |
617 |
return; |
return; |
618 |
if ((flags & XBOARD) && c == '&') |
if ((flags & XBOARD) && c == '&') |
619 |
return; |
return; |
634 |
*/ |
*/ |
635 |
if (flags & XBOARD) { |
if (flags & XBOARD) { |
636 |
if (score > MATE-255) { |
if (score > MATE-255) { |
637 |
printf ("%d%c Mat%d %d %ld\t", Idepth/DEPTH, c, |
printf ("%d%c Mat%d %d %ld\t", Idepth, c, |
638 |
(int)(MATE+2-abs(score))/2, (int)(ElapsedTime), NodeCnt+QuiesCnt); |
(int)(MATE+2-abs(score))/2, (int)(ElapsedTime), NodeCnt+QuiesCnt); |
639 |
if (ofp != stdout) |
if (ofp != stdout) |
640 |
fprintf (ofp,"%2d%c%7.2f Mat%02d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
fprintf (ofp,"%2d%c%7.2f Mat%02d%10ld\t", Idepth, c, ElapsedTime, |
641 |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
642 |
} else if (score < -MATE+255) { |
} else if (score < -MATE+255) { |
643 |
printf ("%d%c -Mat%2d %d %ld\t", Idepth/DEPTH, c, |
printf ("%d%c -Mat%2d %d %ld\t", Idepth, c, |
644 |
(int)(MATE+2-abs(score))/2, (int)(ElapsedTime), NodeCnt+QuiesCnt); |
(int)(MATE+2-abs(score))/2, (int)(ElapsedTime), NodeCnt+QuiesCnt); |
645 |
if (ofp != stdout) |
if (ofp != stdout) |
646 |
fprintf (ofp,"%2d%c%7.2f -Mat%02d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
fprintf (ofp,"%2d%c%7.2f -Mat%02d%10ld\t", Idepth, c, ElapsedTime, |
647 |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
648 |
} else { |
} else { |
649 |
printf ("%d%c %d %d %ld\t", Idepth/DEPTH, c, (int)score, |
printf ("%d%c %d %d %ld\t", Idepth, c, (int)score, |
650 |
(int)(ElapsedTime), NodeCnt+QuiesCnt); |
(int)(ElapsedTime), NodeCnt+QuiesCnt); |
651 |
if (ofp != stdout) |
if (ofp != stdout) |
652 |
fprintf (ofp,"%2d%c%7.2f%7d%10ld\t", Idepth/DEPTH, c, |
fprintf (ofp,"%2d%c%7.2f%7d%10ld\t", Idepth, c, |
653 |
ElapsedTime, score, NodeCnt+QuiesCnt); |
ElapsedTime, score, NodeCnt+QuiesCnt); |
654 |
} |
} |
655 |
} |
} |
656 |
else { /* Not XBOARD */ |
else { /* Not XBOARD */ |
657 |
if (score > MATE-255) { |
if (score > MATE-255) { |
658 |
printf ("\r%2d%c%7.2f Mat%02d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
printf ("\r%2d%c%7.2f Mat%02d%10ld\t", Idepth, c, ElapsedTime, |
659 |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
660 |
if (ofp != stdout) |
if (ofp != stdout) |
661 |
fprintf (ofp,"\r%2d%c%7.2f Mat%02d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
fprintf (ofp,"\r%2d%c%7.2f Mat%02d%10ld\t", Idepth, c, ElapsedTime, |
662 |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
663 |
} else if (score < -MATE+255) { |
} else if (score < -MATE+255) { |
664 |
printf ("\r%2d%c%7.2f -Mat%02d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
printf ("\r%2d%c%7.2f -Mat%02d%10ld\t", Idepth, c, ElapsedTime, |
665 |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
666 |
if (ofp != stdout) |
if (ofp != stdout) |
667 |
fprintf (ofp,"\r%2d%c%7.2f -Mat%02d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
fprintf (ofp,"\r%2d%c%7.2f -Mat%02d%10ld\t", Idepth, c, ElapsedTime, |
668 |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
(MATE+2-abs(score))/2, NodeCnt+QuiesCnt); |
669 |
} else { |
} else { |
670 |
printf ("\r%2d%c%7.2f%7d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
printf ("\r%2d%c%7.2f%7d%10ld\t", Idepth, c, ElapsedTime, |
671 |
score, NodeCnt+QuiesCnt); |
score, NodeCnt+QuiesCnt); |
672 |
if (ofp != stdout) |
if (ofp != stdout) |
673 |
fprintf (ofp,"\r%2d%c%7.2f%7d%10ld\t", Idepth/DEPTH, c, ElapsedTime, |
fprintf (ofp,"\r%2d%c%7.2f%7d%10ld\t", Idepth, c, ElapsedTime, |
674 |
score, NodeCnt+QuiesCnt); |
score, NodeCnt+QuiesCnt); |
675 |
} |
} |
676 |
} |
} |