Author: Michel Langeveld
Date: 07:28:54 01/13/04
The idea of Nullmove is that you let a player have the right to do two moves
during a game. If he can't win with this right then his position is really bad,
and we count it as lost.
--------------------------------------------------------------------------------
original
6 318 343459 -8 b1c3 b8c6 i1h3 d7d6 h3f4 c8f5
7 1782 2188112 3 b1c3 d7d5 d2d4 c8f5 i1h3 i8h6 c1f4
nullmove with: if (!c && !nullmoved && depth - 1 - R > 0)
6 215 227824 -8 b1c3 b8c6 i1h3 d7d6 h3f4 c8f5
7 859 1008458 3 i1h3 d7d5 d2d4 c8f5 b1c3 i8h6 c1f4
nullmove with :if (!c && !nullmoved)
6 59 63778 -3 i1h3 d7d6 g1f3 i8h6 b1c3 b8c6
7 342 403509 3 i1h3 d7d5 d2d4 c8f5 c1f4 i8h6 b1c3
My question is do I have to protect that after a nullmove we go immediatly into
quiesce or can I live without this protection?
--------------------------------------------------------------------------------
/* search() does just that, in negamax fashion */
int search(int alpha, int beta, int depth)
{
int i, j, x;
int his_piece;
BOOL c, f;
int best_score;
/* we're as deep as we want to be; call quiesce() to get
a reasonable score and return it. */
if (depth <= 0)
return quiesce(alpha,beta);
++nodes;
/* do some housekeeping every 1024 nodes */
if ((nodes & 1023) == 0)
checkup();
pv_length[ply] = ply;
/* if this isn't the root of the search tree (where we have
to pick a move and can't simply return 0) then check to
see if the position is a repeat. if so, we can assume that
this line is a draw and return 0. */
if (ply && reps())
return 0;
/* are we too deep? */
if (ply >= MAX_PLY - 1)
return eval();
if (hply >= HIST_STACK - 1)
return eval();
/* are we in check? */
c = in_check(side);
//we are not check and did not do a nullmove before
//Question : what if clausule can we use here?
if (!c && !nullmoved)
{
//set the end marker
first_move[ply + 1] = first_move[ply];
makenullmove();
x = -search(-beta, -beta + 1, depth - 1 - R);
takebacknullmove();
if (x >= beta)
return beta;
//restore that fact that we are not check
c = FALSE;
}
/* if we are in check don't seach deeper */
if (c) depth++;
gen();
if (follow_pv) /* are we following the PV? */
sort_pv();
f = FALSE;
best_score = -10000;
/* loop through the moves */
for (i = first_move[ply]; i < first_move[ply + 1]; ++i) {
sort(i);
if (!makemove(gen_dat[i].m))
continue;
f = TRUE;
if (best_score == -10000)
x = -search(-beta, -alpha, depth - 1);
else
{
x = -search(-(alpha + 1), -alpha, depth - 1);
if (x > alpha && x < beta)
{
x = -search(-beta, -alpha, depth - 1);
}
}
takeback();
if (x > best_score) {
best_score = x;
if (x > alpha) {
/* this move caused a cutoff, so increase the history
value so it gets ordered high next time we can
search it */
if (x >= beta) {
addkiller(gen_dat[i].m);
his_piece = piece[gen_dat[i].m.b.from];
history[side][his_piece][gen_dat[i].m.b.to] += depth;
return beta;
}
alpha = x;
/* update the PV */
pv[ply][ply] = gen_dat[i].m;
for (j = ply + 1; j < pv_length[ply + 1]; ++j)
pv[ply][j] = pv[ply + 1][j];
pv_length[ply] = pv_length[ply + 1];
}
}
}
/* no legal moves? then we're in checkmate or stalemate */
if (!f) {
if (c)
return -10000 + ply;
else
return 0;
}
/* fifty move draw rule */
if (fifty >= 100)
return 0;
return best_score;
}
This page took 0.01 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.