It was exasperating trying to get my KPK codes to work. With bitases, it should be simple to implement the KPK routine. Basically, it is to return zero when probe to bitbase shows a draw. For a win, what I found needed is just to evaluate the distance to promotion for the pawn. The other evaluation is just that the lone king stays clear from the pawn and the promotion square. It is this simple. Yet it was not working!
What actually made it work this time around is I disabled all the lines of codes that involves fifty and repetition draws in my search functions. I think there are bugs. I have yet to examine what was wrong.
There is something that need to be noted about the KPK routine. For some 'difficult' KPK endings, it seems necessary to have the two pawn/lone king race to promotion and also the Kings' race to get near the pawn. Without these coding, the play may fail. I don't clearly know the reason yet.
My evalKPK() codes is here:
Code: Select all
int evalkpk(const int side) {
const int pcol = !bits[0][Pawn], xpcol = pcol ^ 1;
const int pK = king[pcol], loneK = king[xpcol], p = firstone(bits[pcol][Pawn]);
const int promsq = PROMOTE_SQ(p, pcol);
int probeWk, probeBk, probeWp;
int win, index, stm;
int x, d1, d2;
/* safe capture of pawn */
if (kMap[king[side]] & bits[side ^ 1][Pawn] & ~kMap[king[side ^ 1]]) {
return (side == pcol ? 2 : -2);
}
/* pawn/loneK race to promote. */
if (!(FORWARD_ROW_BITS(p, pcol) & rMap[p]->file & bits[pcol][King])) {
/* path ahead clear */
d1 = DIST(p, promsq);
d2 = DIST(loneK, promsq) - (side ^ pcol);
if (d2 > d1) {
/* promote success */
x = v8Pawn - DIST(p, promsq);
return (side == pcol ? x : -x);
}
}
/* kings' race to protect pawn. */
d1 = DIST(p, pK);
d2 = DIST(p, loneK) - (side ^ pcol);
if (d1 <= d2 + 1); /* protect success */
else {
/* pawn lost */
x = 2 + d2;
return (side == pcol ? x : -x);
}
/* probe kpk bitbase (as white with the pawn) */
if (pcol == 0) {
/* my internal chess board square mapping is unusual, (a1, a2, a3,...) -> (0, 1, 2, ...)
* convert to mapping of bitbase */
probeWk = sqMapA1B1[pK];
probeBk = sqMapA1B1[loneK];
probeWp = sqMapA1B1[p];
stm = side;
} else {
/* flip everything */
probeWk = 63 - sqMapA1B1[pK];
probeBk = 63 - sqMapA1B1[loneK];
probeWp = 63 - sqMapA1B1[p];
stm = side ^ 1;
}
index = 2 * ((probeBk >> 3) + 8 * probeWk + 8 * 64 * ((probeWp - 8) >> 1)) + 1 * stm;
/* probe bitbase; 1 == win, 0 == draw */
win = (bitbase[index] >> (probeBk & 7)) & 1;
if (!win) {
return (side == pcol ? 2 : -2);
}
/* Now a win. The evaluation needed is this simple! */
x = v7Pawn
- 1 * DIST(p, promsq)
+ 4 * DIST(loneK, p)
+ 4 * DIST(loneK, promsq);
return (side == pcol ? x : -x);
[D]4k3/8/8/8/K7/8/4P3/8 w - - 5 1[/D]
Best Regards,
Rasjid.