Re: How to implement KPK ?
Posted: Thu Mar 21, 2013 11:33 am
The white pass and black pass look very similar, so perhaps it is more elegant to merge them into one routine:
I guess the bk == p positions should be set to -1 in Init(), and not to 1; the Pass() code does not ever test the state of the daughter position in dtc when it captures the black King with a Pawn, but just assigns a win. So the only testing of this position that ever is important is when the black King stepped onto the Pawn, whether on the previous ply or longer before that. The btm cases have to be marked as draw, to prevent black being forced to 'step off' the Pawn again by zugzwang when white does not have a King move to capture the black King, and tries another one.
Code: Select all
void
Pass (int stm)
{
int wk, bk, p, d;
for(wk=0; wk<64; wk++) for(bk=0; bk<64; bk++) for(p=0; p<64; p++) {
int k = stm == WTM ? wk : bk
int O88 = (k & 070) + k; // 0x88 square number of King
if(dtc[stm][wk][p][bk]) continue; // already decided
dtc[stm][wk][p][bk] = stm; // assume lost if btm, undecided if wtm
if(bk != p && stm == WTM) { // pawn not captured, so can move
if(p+8 != bk && dtc[BTM][wk][p+8][bk] > 0) { dtc[WTM][wk][p][bk] = 1; continue; }
if(p+7 == bk && (p & 7) != 0) { dtc[WTM][wk][p][bk] = 1; continue; }
if(p+9 == bk && (p & 7) != 7) { dtc[WTM][wk][p][bk] = 1; continue; }
}
for(d=0; d<8; d++) {
int to = O88 + steps[d];
if(to & 0x88) continue; // off board
if(stm == WTM ? dtc[BTM][to][p][bk] > 0 : dtc[WTM][wk][p][to] > 0)
{ dtc[stm][wk][p][bk] = !stm; break; }
}
}
}
void
Build ()
{
int i;
Init();
for(i=0; i<100; i++) // won't take more than 100 moves
Pass(WTM), Pass(BTM);
Pack();
}