From: H.G.Muller Date: Tue, 10 Apr 2018 15:42:31 +0000 (+0200) Subject: Implement promotion drops X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=29db067bd8cc5b56686bdd78c2a4092f1ea1c4a6;p=crazywa.git Implement promotion drops The various routines for generating drop moves are now also able to generate drops of the promoted version of the piece in hand, controlled by a variable 'promoDrops'. For now this variable is set to forbid such drops. --- diff --git a/dropper.c b/dropper.c index 9685e96..e7b834c 100644 --- a/dropper.c +++ b/dropper.c @@ -65,7 +65,7 @@ int moveNr; // part of game state; incremented by MakeMove #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]; @@ -485,6 +485,7 @@ GameInit (char *name) 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); @@ -905,10 +906,22 @@ CheckDrops (int stm, int king) 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 @@ -924,7 +937,7 @@ CheckDrops (int stm, int king) 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' @@ -937,6 +950,11 @@ EvasionDrops (int stm, StackFrame *f, int mask) } 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 @@ -958,6 +976,10 @@ AllDrops (int stm) 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