Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc
Moderator: Andres Valverde
by Uri Blass » 27 Nov 2004, 10:46
I still do not have a tool to analyze epd automatically.
There are basically 2 ways that I can think about:
1)Writing a new thread that will give the engine the impression that it gets winboard commands under analysis mode.
2)adding more option for analyze varaible.
today there are 3 values that analyze can get(note that it is used only when the engine is searching so it's value is unimportant in force mode):
analyze = PLAY_MODE
analyze=PONDER_MODE
analyze=ANALYSIS_MODE
It is possible to add analyze_epd mode when the program may look at some global variables only if analyze=analyze_epd mode to decide when to stop the analysis (more varaibles can be for example time arrayt that will give time for every position in the epd file because I may want to give different times for different positions).
Option 1 has the advantage of being more general but option 2 seems to me more easy to write when I have no idea how to write option 1 because I have no experience in threads and I also need to translate the information that I get from the engine to some analysis file in that case.
What is your opinion?
Do you have a function to read epd files and if yes what design do you use to do it.
Uri
-
Uri Blass
-
- Posts: 727
- Joined: 09 Oct 2004, 05:59
- Location: Tel-Aviv
by milix » 27 Nov 2004, 15:57
Hi Uri.
In AICE I have a special command 'epdtest' yhat takes two arguments: The time or depth we want to spend for each epd position and an epd file name. AICE opens the file, reads the position and for each position it setups the board and calls the think() function. So basically it emulates a new game for a given starting position. Here is my code for epdtest function, I hope it helps:
- Code: Select all
void Engine::on_epdtest(CMSG& msg)
{
FILE* fp;
int res;
char* args;
bool log=true;
char epdtest[256];
char epdfile[256];
char buff[256];
int i, tests, solved;
long totnodes, nodes;
clock_t totdiff, tdiff, start, end;
// parse command's arguments
args = (char*)msg.lParam;
if (tolower(*args)=='d') {
args++;
m_level.type = LEVEL_DEPTHSEARCH;
m_level.u1.depth = atoi(args);
if ((unsigned)m_level.u1.depth > MAX_DEPTH) m_level.u1.depth = MAX_DEPTH;
} else if (tolower(*args)=='t') {
args++;
m_level.type = LEVEL_MOVETIME;
m_level.u1.secs_per_move = atoi(args);
if ((unsigned)m_level.u1.secs_per_move > 3600)
m_level.u1.secs_per_move = 3600;
} else {
output(log, "Syntax is: epdtest <dDEPTH>|<tSECS> <EPD file name>\n");
return;
}
while (*args && (*args==' ' || isdigit(*args))) args++;
strcpy(epdfile, args);
// open EPD file
fp = fopen(epdfile, "rt");
if (!fp) {
strcpy(epdtest, epdfile);
strcpy(epdfile, "tests/");
strcat(epdfile, epdtest);
fp = fopen(epdfile, "rt");
if (!fp) {
output(log, "Error opening EPD file.\n");
return;
}
}
if (m_level.type == LEVEL_DEPTHSEARCH) {
output(log, "RUNNING EPD TEST \"%s\" @ DEPTH %d\n", epdfile, m_level.u1.depth);
} else {
output(log, "RUNNING EPD TEST \"%s\" @ %d SECONDS PER POSITION\n", epdfile, m_level.u1.secs_per_move);
}
// start tests
totnodes = 0;
totdiff = 0;
tests = solved = 0;
unsigned long tnull=1, tnullcuts=0;
unsigned long tdepth=0, tfh=1, tfhf=0;
for (;;) {
if (!fgets(epdtest, 256, fp)) break;
if (brd->setup(epdtest) != OK) {
output(log, "Error in EPD position %s\n", epdtest);
continue;
}
initnew();
brd->generate_legal();
sprintf(buff, "%s %s (best move: %s", brd->epd_id.c_str(),
brd->turn==WHITE ? "WTM" : "BTM",
brd->move2str(brd->epd_bm[0], N_ALGEBRAIC));
i = 1;
while (!IsNullMove(brd->epd_bm[i])) {
strcat(buff, " ");
strcat(buff, brd->move2str(brd->epd_bm[i], N_ALGEBRAIC));
i++;
}
output(log, "%s)\n", buff);
memset(&stats, 0, sizeof(stats));
m_color = brd->turn;
msg.type = MSG_NONE;
start = time_ms();
res = think();
end = time_ms();
nodes = m_nodes;
totnodes += nodes;
tdiff = end - start;
totdiff += tdiff;
tests++;
tdepth += stats.depth;
tnull += stats.nm_searches;
tnullcuts += stats.nm_cuts;
tfh += stats.fh_total;
tfhf += stats.fh_first;
bool found = false;
while (!found && --i>=0) {
if (SameMove(m_bestmove, brd->epd_bm[i])) found = true;
}
if (found) {
output(log, "SOLVED! ");
solved++;
} else {
output(log, "Failed. ");
}
if (mcl::abs(m_pv.score[0]) >= MATE-MAX_MATE_DEPTH) {
output(log, "found %s %s #%d, depth %d, %d KN in %.2f sec",
brd->move2str(m_bestmove, N_LONGALGEBRAIC),
evaluation_text(m_pv.score[0], m_color), mate_score(m_pv.score[0]),
stats.depth, nodes/1000, (double)tdiff/1000);
} else {
output(log, "found %s %s (%.2f) depth %d, %d KN in %.2f sec",
brd->move2str(m_bestmove, N_LONGALGEBRAIC),
evaluation_text(m_pv.score[0], m_color),
m_pv.score[0]/100.0, stats.depth, nodes/1000, (double)tdiff/1000);
}
if ((double)tdiff/1000 <= 0.001) output(log, ", REALLY GREAT KN/sec!\n");
else output(log, ", %.1f KN/sec\n", (double)(nodes/1000)/((double)tdiff/1000));
output(log, "Hash hits %.1f%%, cutoffs %.1f%%, nullmove %.1f%% move ordering %.1f%%\n\n",
100.0*stats.ht_hits/stats.ht_probs, 100.0*(stats.ht_hits-stats.ht_miss)/stats.ht_probs,
100.0*((double)stats.nm_cuts/stats.nm_searches), 100.0*((double)stats.fh_first/stats.fh_total));
}
fclose(fp);
output(log, "\nTOTALS: Tests %d Solved %d (%.1f%%), depth %.1f, %d KN in %.2f sec (%.1f KN/sec)\n",
tests, solved, 100.0*solved/tests, (float)tdepth/tests, totnodes/1000, (double)totdiff/1000, (double)(totnodes/1000)/((double)totdiff/1000));
output(log, "Successful nullmove searches: %.1f%%, move ordering %.1f%%\n",
100.0*((double)tnullcuts/tnull), 100.0*((double)tfhf/tfh));
}
-
milix
-
- Posts: 54
- Joined: 04 Nov 2004, 19:36
- Location: Greece
-
Return to Programming and Technical Discussions
Who is online
Users browsing this forum: No registered users and 9 guests