Author: Dann Corbit
Date: 16:50:11 05/31/02
Go up one level in this thread
On May 31, 2002 at 18:50:18, Omid David wrote:
>I forgot to change "negascout" to "AlphaBeta" in 7th line for better
>illustration. Here is the correction:
>
>int AspWin(int estimate, int delta, int depth)
>{
>int alpha = estimate - delta;
>int beta = estimate + delta;
>int best;
>
>best = AlphaBeta(alpha, beta, depth);
>
>/* re-search */
>if(best <= alpha)
>best = AlphaBeta(-10000, beta, depth);
>else if(best >= beta)
>best = AlphaBeta(alpha, 10000, depth);
>
>/* is there any better way to handle this very rare case? */
>if(best >= beta || best <= alpha)
>best = AlphaBeta(-10000, 10000, depth);
>
>return best;
>}
ExChess does this:
/*----------------------- Search function ---------------------*/
// Driver for the search process. 1st initialize important data
// structures, the do iterative deeping until time runs out.
move search(position p, int time_limit, int T)
{
char outstring[60], mstring[10];
int g, done, pvi;
long elapsed;
position pv_pos;
turn = T;
root_wtm = p.wtm;
nomove.t = 0;
#if DEBUG
outfile.open("search.log");
#endif
// logging the current position in FEN format
if(logging) {
logfile <<
"---------------------------------------------------------------\n";
logfile << "Starting search on position:\n";
int lcount; square lsqr;
for(int rank = 7; rank >= 0; rank--) {
lcount = 0;
for(int file = 0; file < 8; file++) {
lsqr = p.sq[SQR(file,rank)];
if(lsqr.type) {
if(lcount) { logfile << lcount; lcount = 0; }
if(lsqr.side)
logfile << name[lsqr.type];
else logfile << bname[lsqr.type];
} else lcount ++;
}
if(lcount) logfile << lcount;
if(rank) logfile << "/";
}
if(p.wtm) logfile << " w ";
else logfile << " b ";
if(p.castle&1) logfile << "K";
if(p.castle&2) logfile << "Q";
if(p.castle&4) logfile << "k";
if(p.castle&8) logfile << "q";
if(!p.castle) logfile << "-";
if(p.ep)
logfile << " " << char(FILE(p.ep) + 97) << (RANK(p.ep) + 1);
else logfile << " -";
logfile << "\n";
}
// Set start of search depth
if(pc[0][0].t == p.last.t && pc[0][0].t) {
start_depth = MAX(last_depth-1, 1);
} else if(pc[0][1].t == p.last.t && pc[0][1].t && !last_ponder) {
start_depth = MAX(last_depth-2, 1);
} else {
start_depth = 1;
}
// setting counts to zero
node_count = 0; eval_count = 0; time_count = 0;
phash_count = 0; hash_count = 0; hmove_count = 0; q_count = 0;
null_cutoff = 0; extensions = 0; internal_iter = 0;
egtb_probes = 0; egtb_hits = 0; fail_high = 0; first_fail_high = 0;
time_check_interval = 500;
// setup some search parameters - for old hash entries
if(h_id > 100 || h_id < 0) h_id = 1;
h_id++;
// is this a pondering session, if so - make the move from the pv
if(ponder) {
if(book && !pc[0][1].t) ponder_move = opening_book(p.hcode, p);
else ponder_move = pc[0][1];
if(ics) { ics = 0; print_move(p, ponder_move, mstring); ics = 1; }
else print_move(p, ponder_move, mstring);
if(ponder_move.t) {
if(!exec_move(&p, ponder_move, 0)) { ponder_time = 0; return nomove; }
} else { ponder_time = 0; return nomove; }
if(!ALLEG && post) {
cout << "Hint: " << mstring << "\n";
cout.flush();
}
if(logging) logfile << "***** Ponder Move: " << mstring << " *****\n";
// add ponder move to position list
p_list[T-1] = p.hcode;
// set ponder time doubling
ponder_time_double = 0;
}
// initializing eval
init_score(&p, T);
// checking tablebases at root
#if TABLEBASES
if(p.pieces[0] + p.pieces[1]
+ p.plist[0][PAWN][0] + p.plist[1][PAWN][0] <= EGTB) {
root_tb_score = probe_tb(&p, 0);
} else root_tb_score = -1;
#else
root_tb_score = -1;
#endif /* TABLEBASES */
// checking book
if(book && !ponder) {
book_search = 1;
bookm = opening_book(p.hcode, p);
book_search = 0;
if(bookm.t) {
pc[0][0] = bookm; pc[0][1].t = 0;
if(logging) {
if(ics) { ics = 0; print_move(p, bookm, mstring); ics = 1; }
else print_move(p, bookm, mstring);
logfile << "Book Move Found: " << mstring << "\n";
}
learn_positions[T-1].hcode.key = 0;
learn_positions[T-1].hcode.address = 0;
return pc[0][0];
} else {
no_book++;
if(no_book >= 3) book = 0;
}
}
// if last search was a ponder and if user made expected move and
// if ponder time is greater than limit, return best move
if(last_ponder && ponder_time >= (time_limit<<ponder_time_double) &&
p.last.t == ponder_move.t && pc[0][0].t) {
if(logging) {
if(ics) cout << "tellics whisper Guessed last move! Score: "
<< g_last << " Ply: " << last_depth << "\n";
if(ics) { ics = 0; print_move(p, pc[0][0], mstring); ics = 1; }
else print_move(p, pc[0][0], mstring);
logfile << "Guessed Last Move! Returning: " << mstring << "\n";
}
cout.flush();
if(T>2 && T<MAX_GAME_PLY-1) predicted[T-3] = 1;
return pc[0][0];
}
if(last_ponder && p.last.t == ponder_move.t && pc[0][0].t && !book_search) {
start_depth = MAX(last_depth-1,1);
h_id--; // reset hash id to mark entries as current
if(logging) {
logfile << "Guessed last move, but searching deeper...\n";
if(ics) cout << "tellics whisper Guessed last move, searching deeper...\n";
}
cout.flush();
// set target time
limit = (time_limit<<ponder_time_double) - ponder_time;
} else {
pc[0][0].t = NOMOVE; // clear first move in the pv
limit = time_limit; // set target time
}
// set the learn position information to zero unless
// we have something to put in
if(!tsuite && !analysis_mode && !book_search
&& T < MAX_GAME_PLY-1 && T) {
learn_positions[T-1].hcode.key = 0;
learn_positions[T-1].hcode.address = 0;
}
// we didn't predict the last move - for learning info
if(start_depth == 1 && T > 2 && T < MAX_GAME_PLY-1) predicted[T-3] = 0;
else if(T > 2 && T < MAX_GAME_PLY-1) predicted[T-3] = 1;
last_ponder = 0;
ponder_time = 0;
max_limit = int(MIN(4*time_limit, timeleft/6.0));
if(!tsuite && !analysis_mode) {
limit = MIN(max_limit, limit);
if(timeleft < 500) {
start_depth = 1;
time_check_interval = 50;
}
}
start_time = GetTime();
last_depth = 1;
// adjusting hash code for game stage
or(p.hcode, stage_code[stage]);
// initialize history table
for(int i = 0; i < 64; i++)
for(int j = 0; j < 64; j++) history[i][j] = 0;
if(logging) {
logfile << "Target search time: " << time_limit << "\n";
logfile << "Starting depth: " << start_depth << "\n";
logfile << "Game stage: " << stage << "\n";
}
// Main search loop for iterative deeping
for(max_ply = start_depth; max_ply < MAXD-1; max_ply++)
{
sp[0] = p;
node_count++;
max_depth = max_ply;
if(max_ply != start_depth)
{ root_alpha = g_last-25; root_beta = g_last+25; }
else
{ root_alpha = -MATE; root_beta = +MATE; }
done = 2;
while(1) {
g = pvs(root_alpha, root_beta, (max_ply-1)*UNIT_DEPTH+INIT_EXT, 0);
if(g == -TIME_FLAG) break;
if(g <= root_alpha) {
if(done == 2) {
root_beta = root_alpha+1; root_alpha = -MATE;
} else if(done == 1) {
root_beta = +MATE; root_alpha = -MATE;
} else break;
done--;
} else if(g >= root_beta) {
if(done == 2) {
root_alpha = root_beta-1; root_beta = +MATE;
} else if(done == 1) {
root_beta = +MATE; root_alpha = -MATE;
} else break;
done--;
} else break;
}
if(!pc[0][0].t && start_depth != 1) {
start_depth = 1;
max_ply = 0;
continue;
}
// writing pv into hash table to be searched first
pv_pos = p; pvi = 0;
while(pc[0][pvi].t) {
put_move(pv_pos.hcode, pc[0][pvi].t);
exec_move(&pv_pos, pc[0][pvi], 0);
if(pvi > 1 && !tsuite && !analysis_mode
&& !book_search && T < 255) {
learn_positions[T-1] = pv_pos;
learn_rootpos[T-1] = p;
}
pvi++;
}
if(post && !ics && g != -TIME_FLAG) {
search_display(g, start_time, node_count, max_ply);
best_depth = max_ply;
}
// if time is up, or we found a mate... break
if(inter() || g == -TIME_FLAG) break;
g_last = g;
last_depth = max_ply;
if((g == 0 && max_ply > MAXD-3) ||
((g > (MATE>>1) || g < -(MATE>>1)) && max_ply > 2)) break;
}
elapsed = GetTime() - start_time; if(!elapsed) elapsed = 1;
if(ponder) {
last_ponder = 1; ponder_time = elapsed;
}
// adjusting hash code for game stage
or(p.hcode, stage_code[stage]);
if(!xboard && !ALLEG && post) {
cout << "\nnode_count = " << node_count
<< " quiescent nodes = " << q_count
<< " eval_count = " << eval_count << "\n";
cout << "hash hits = " << hash_count
<< " hash moves = " << hmove_count
<< " pawn hash hits = " << phash_count << "\n";
cout << "node_rate = " << int(100.0*(float(node_count)/float(elapsed)))
<< " null cuts = " << null_cutoff
<< " exten = " << extensions
<< " int_iter = " << internal_iter << "\n";
cout << "egtb_probes = " << egtb_probes
<< " egtb_hits = " << egtb_hits
<< " fail_high(%) = " <<
int(100.0*(float(first_fail_high)/float(fail_high))) << "\n";
}
if(logging) {
logfile << "node_count = " << node_count
<< " quiescent nodes = " << q_count
<< " eval_count = " << eval_count << "\n";
logfile << "hash hits = " << hash_count
<< " hash moves = " << hmove_count
<< " pawn hash hits = " << phash_count << "\n";
logfile << "node_rate = " << int(100.0*(float(node_count)/float(elapsed)))
<< " null cuts = " << null_cutoff
<< " exten = " << extensions
<< " int_iter = " << internal_iter << "\n";
logfile << "egtb_probes = " << egtb_probes
<< " egtb_hits = " << egtb_hits
<< " fail_high(%) = " <<
int(100.0*(float(first_fail_high)/float(fail_high))) << "\n";
}
// Kibitz the search results to ics server
if(ics && !ALLEG && !ponder && logging) {
if(xboard) sprintf(outstring, "tellics whisper ");
else sprintf(outstring, "\n Search summary: ");
cout << outstring;
if(wbest > (MATE>>1)) {
sprintf(outstring, "MATE+(in %i moves) ", (MATE-wbest)>>1);
} else if(wbest < -(MATE>>1)) {
sprintf(outstring, "MATE-(in %i moves) ", (MATE+wbest)>>1);
} else if(wbest >= 0) {
sprintf(outstring, "+%.2f, ", float(wbest)/value[PAWN]);
} else {
sprintf(outstring, "%.2f, ", float(wbest)/value[PAWN]);
}
cout << outstring;
if (elapsed >= 5)
sprintf(outstring, "%i ply, nps: %.0f ",
wply, float(node_count*100)/elapsed);
else sprintf(outstring, "%i ply ", wply);
cout << outstring;
cout << "\n";
}
#if DEBUG
outfile.close();
#endif
// learning if applicable
if(!ponder && learn_bk && BOOK_LEARNING) {
if(!book && learn_count > 0 && wbest > +LEARN_SCORE)
{ book_learn(1); learned = learn_count; learn_count = -1; }
else if(!book && learn_count > 0 && wbest < -LEARN_SCORE)
{ book_learn(0); learn_count = -1; }
else if(learned && wbest < -LEARN_SCORE)
{ learn_count = learned; book_learn(-1);
learned = 0; learn_count = -1; }
}
if(wbest < -(MATE>>1) && T < MAX_GAME_PLY-1
&& !tsuite && !analysis_mode && !book_search && td_learning) {
learn_scores = 1;
score_learning(T, p.wtm);
learn_scores = 0;
td_learning = 0;
}
if(logging) {
if(ics) { ics = 0; print_move(p, pc[0][0], mstring); ics = 1; }
else print_move(p, pc[0][0], mstring);
if(!ponder)
logfile << "Return move from search: " << mstring << "\n";
if(ponder) {
logfile << "***** Pondering ended ***** Time: " << ponder_time
<< ", Time required doublings: " << ponder_time_double << "\n";
}
logfile <<
"---------------------------------------------------------------\n";
}
return pc[0][0];
}
This page took 0 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.