That seems simpler, and much less bug-prone then the code you are trying to write now.
Let me make a first attempt. (Completely untested...)
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*62*64*6];
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
BlackPass ()
{
int wk, bk, p, d;
for(wk=0; wk<64; wk++) for(bk=0; bk<64; bk++) for(p=0; p<64; p++) {
int O88 = (bk & 070) + bk; // 0x88 square number
if(dtc[BTM][wk][p][bk]) continue; // already decided
dtc[BTM][wk][p][bk] = 1; // assume lost, if no escape will be found
for(d=0; d<8; d++) {
int to = O88 + steps[d];
if(to & 0x88) continue; // off board
if(dtc[WTM][wk][p][to] <= 0) { dtc[BTM][wk][p][bk] = 0; break; } // escape
}
}
}
void
WhitePass ()
{
int wk, bk, p, d;
for(wk=0; wk<64; wk++) for(bk=0; bk<64; bk++) for(p=0; p<64; p++) {
int O88 = (wk & 070) + wk; // 0x88 square number
if(dtc[WTM][wk][p][bk]) continue; // already decided
if(bk != p) { // 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(dtc[BTM][to][p][bk] > 0) { dtc[WTM][wk][p][bk] = 1; 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++) {
int index = (bk >> 3) + 8*wk + 8*64*(p-8);
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
WhitePass(), BlackPass();
Pack();
}