# Computer Chess Club Archives

## Messages

### Subject: Question about details of hashing (olithink)

Author: Michel Langeveld

Date: 11:31:24 01/22/04

```Olithink uses hashing as follow in its search.c.
Questions in the code marked with //

int search(int on_move, int ply, int depth, int alpha, int beta, int do_null)
{
int n, i, j, w, c, hflag, nolegal;
Move bestmove = 0, move = 0;

if ((++nodes & 0x1fff) == 0) {
if (bioskey()) inputmove(pmove ? ONMOVE(pmove) : COL_N);
if (!pmove && (nodes*10)/nps*250 > mytime) { sabort = 1; return alpha; }
}

if (ply && depth && checkfordraw(1)) return 0;
pvlength[ply] = ply;

c = attacked(kingpos[on_move], on_move);
if (c) depth++;
else if (nstack && IS_PROM(movestack[nstack-1])) depth++;
if (depth < 0) depth = 0;

//*** Ply gets updated each move ... Why does it not look in the hash
//*** If ply == 0?

hflag = lookUpH(depth, &w, &move);
if (ply && hflag) {
if (hflag == 1) if (w >= beta) return beta;
if (hflag == 2) { do_null = 0; if (w < alpha) return alpha; }
}

//*** hflag == 0 means NULLMOVE
//*** hflag == 1 means hashscore was >= beta
//*** hflag == 2 means hashscore was <= alpha
//*** hflag == 4 means EXACT bound

//*** why doesn't it use EXACT and NULLMOVES, is this non-optimal impl?

if (!c && do_null && depth && ply && bitcount(R000BitB[on_move] &
(~R000BitB[PAWN[on_move]])) > 3) {
donullmove();
w = -search(on_move^1, ply+1, depth - 3 - (depth > 5), -beta, -beta + 1, 0);
undonullmove();
if (w >= beta) {
storeH(0, depth, w, 1);
return w;
}
}

if (!ply) move = pv[0][0];
hashmv[ply] = move;
hflag = move ? 1 : 0;
nolegal = 1;
n = 0;

if (depth == 0 && !c) {
w = eval(on_move, alpha, beta);
if (w > alpha) alpha = w;
if (alpha >= beta) return beta;

//Funny QSearch implementation ... this generates
//captures
n = generate_moves(on_move, ply, 1);
if (n == 0) return w;
hflag = 0;
}

i = 0;
do {
if (i == 1) hflag = 0;
if (n == 0 && !hflag) {
if (c) 	n = generate_check_esc(on_move, ply, 0);
else n = generate_moves(on_move, ply, 0);

if (i == 1) {
for (j = 0; j < n; j++) {
if (IDENTMV(movelist[j][ply], hashmv[ply])) {
movelist[j][ply] = movelist[n-1][ply];
break;
}
}
}
if (n == 0) break;
}
if (!hflag) move = pick(ply, n-i);
if (!depth && !c && P_TO(move) != EMPTY && swap(move) < -150) continue;

domove(move);
if (!c && attacked(kingpos[on_move], on_move)) { undomove(); continue;}
w = -search(on_move^1, ply+1, depth-1, -beta, -alpha, 1);
if (nolegal) nolegal=0;
undomove();
if (sabort) break;

if (w >= beta)  {
if (P_TO(move) == EMPTY)  {
killer2[ply] = killer[ply];
killer[ply] = move;
}
history[move & 0xFFFF] += depth;
storeH(move, depth, w, 1);
return beta;

//*** Why store score w, and return beta
//*** Doesn't this work bugs in the hand?
}
if (w > alpha) {
pv[ply][ply] = bestmove = move;
for (j = ply+1; j < pvlength[ply+1]; j++) pv[ply][j] = pv[ply+1][j];
pvlength[ply] = pvlength[ply+1];
alpha = w;
if (alpha == 32499 - ply) break;
}
} while (++i < n || hflag);
if (sabort) return alpha;

if (nolegal) {
if (c) return -32500 + ply;
else if (depth) return 0;
} else
storeH(bestmove, depth, alpha, bestmove ? 4 : 2);
return alpha;
}

```