#define promoGain (rawGain + 1)
int pvStack[MAXPLY*MAXPLY/2];
-int nrRanks, nrFiles, specials, pinCodes, maxDrop, moveSP, pawn, queen, lanceMask, knightLim, *pvPtr = pvStack, boardEnd, perpLoses, searchNr;
+int nrRanks, nrFiles, specials, pinCodes, maxDrop, promoDrops, moveSP, pawn, queen, lanceMask, knightLim, *pvPtr = pvStack, boardEnd, perpLoses, searchNr;
int frontier, killZone, impasse, frontierPenalty, killPenalty;
int rawInts[21*22], pieceValues[96], pieceCode[96];
signed char rawChar[32*22], steps[512];
lanceMask = lances[v];
knightLim = (v >= KNIGHTLESS) * 6; // 6 for variants where last piece can be dropped on last two ranks
perpLoses = v; // this works for now, as only zh allows perpetuals
+ promoDrops = 0;
if((p = betza[v])) { // configure GUI for this variant
printf("setup (%s) %dx%d+%d_%s %s 0 1", ptc[v], nrFiles, nrRanks, maxDrop+1, (pieces == waIDs ? "chu" : "shogi"), startPos);
int i, lowest = 0;
if(perpLoses) lowest = !!(pawnCount[sqr2file[king]] & maxBulk[stm]); // in Shogi no Pawn if file already crowded with those
else lowest = (stm == WHITE ? king < 2*22 : king >= 6*22); // in zh no Pawn from back rank
- for(i=maxDrop; i>=lowest; i--) {
+ for(i=maxDrop; i>=0; i--) {
int piece = stm + i, from = handSlot[piece^COLOR];
if((signed char)board[from] < -1) { // piece type is in hand
- int step, dir = 2*firstDir[piece-WHITE];
+ int step, dir;
+ if(promoDrops) { // for variants that also can drop promoted side up
+ dir = 2*firstDir[piece-WHITE+16];
+ while((step = steps[dir++])) {
+ int to = king, range = steps[dir++];
+ while(board[to-=step] == 0) {
+ moveStack[moveSP++] = to + 11 | from << 8;
+ if((range -= 8) <= 0) break;
+ }
+ }
+ }
+ if(i < lowest) break; // suppresses back-rank Pawn drops in zh
+ dir = 2*firstDir[piece-WHITE];
while((step = steps[dir++])) {
int to = king, range = steps[dir++];
if((range & 3) == 2) continue; // non-capture direction
void
EvasionDrops (int stm, StackFrame *f, int mask)
{
- int i, x = f->checker, v = f->checkDir, s = stm ^ COLOR;
+ int i, j, x = f->checker, v = f->checkDir, s = stm ^ COLOR;
while(board[x+=v] == 0) { // all squares on check ray
int last = maxDrop;
if((mask >>= 1) & 1) continue; // suppress 'futile interpositions'
}
if(pawnCount[sqr2file[x]] & maxBulk[stm]) i += !i; // no Pawn in pawn-crowded file
}
+ if(promoDrops) for(j=0; j<=maxDrop; j++) { // all droppable types
+ int piece = s + j, from = handSlot[piece];
+ if((signed char)board[from] < -1) // piece type is in hand
+ moveStack[moveSP++] = from << 8 | x + 11;
+ }
for(; i<=last; i++) { // all droppable types
int piece = s + i, from = handSlot[piece];
if((signed char)board[from] < -1) // piece type is in hand
if(stm == BLACK || !perpLoses) start = badZone;
if(stm == WHITE || !perpLoses) end -= badZone;
}
+ if(promoDrops) { // for variants where pieces can be dropped with either side up
+ for(f=0; f<nrFiles; f++) for(r=0; r<boardEnd; r+=22) // no forbidden ranks then
+ if(board[r+f] == 0) moveStack[moveSP++] = from << 8 | f + r + 11;
+ }
for(f=0; f<nrFiles; f++) {
if(i == 0 && pawnCount[f] & maxBulk[stm]) continue;
for(r=start; r<end; r+=22)