The following code is tested in the sense that it compiles (there was a missing semicolon), and runs without segfaulting (I had forgotten to convert the 0x88 to-square back to a normal square index.)
Code: Select all
/* Public-domain KPK bitbase code by H.G. Muller */
#define WTM 0
#define BTM 1
char dtc[2][64][64][64]; // 512 KB
char bitbase[2*64*64*3];
char steps[] = {1, -1, 16, -16, 15, -15, 17, -17};
void
Init ()
{
int wk, bk, p;
for(wk=0; wk<64; wk++) for(bk=0; bk<64; bk++) for(p=0; p<64; p++) {
if(bk == wk) dtc[BTM][wk][p][bk] = 1, dtc[WTM][wk][p][bk] = -1; else
if(wk == p) dtc[BTM][wk][p][bk] = dtc[WTM][wk][p][bk] = -1; else
if(bk == p) dtc[BTM][wk][p][bk] = -1; else // with WTM black just captured P
if(p >= 56) dtc[WTM][wk][p][bk] = 1; // promoted and on move = win
}
}
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
to -= to>>1 & 070;
if(stm == WTM ? dtc[BTM][to][p][bk] > 0 : dtc[WTM][wk][p][to] > 0)
{ dtc[stm][wk][p][bk] = !stm; break; }
}
}
}
void
Pack ()
{
int wk, bk, p, i;
for(wk=0; wk<64; wk++) for(bk=0; bk<64; bk++) for(p=8; p<56; p+=2) {
int index = (bk >> 3) + 8*wk + 8*64*(p-8>>1);
bitbase[2*index] |= (dtc[WTM][wk][p][bk] > 0) << (bk & 7);
bitbase[2*index+1] |= (dtc[BTM][wk][p][bk] > 0) << (bk & 7);
}
}
void
Build ()
{
int i;
Init();
for(i=0; i<100; i++) // won't take more than 100 moves
Pass(WTM), Pass(BTM);
Pack();
}
Code: Select all
white to move: 211980+, 23085=, 27079-
black to move: 140386+, 113694=, 8064-
[Edit] O, I guess it still needs a stalemate correction.