for (rf = 0; rf < BOARD_HEIGHT; rf++)
for (ff = BOARD_LEFT; ff < BOARD_RGHT; ff++) {
ChessSquare piece;
+ int rookRange = 1000;
if (flags & F_WHITE_ON_MOVE) {
if (!WhitePiece(board[rf][ff])) continue;
&& !SameColor(board[rf][ff], board[rt][ft]))
callback(board, flags, NormalMove,
rf, ff, rt, ft, closure);
- if(gameInfo.variant != VariantFairy && gameInfo.variant != VariantGreat) continue;
+ if(gameInfo.variant == VariantShatranj && gameInfo.variant == VariantCourier) continue; // classical Alfil
rt = rf + rs; // in unknown variant we assume Modern Elephant, which can also do one step
ft = ff + fs;
if (!(rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT)
callback(board, flags, NormalMove,
rf, ff, rt, ft, closure);
}
+ if(gameInfo.variant == VariantSpartan)
+ for(fs = -1; fs <= 1; fs += 2) {
+ ft = ff + fs;
+ if (!(ft < BOARD_LEFT || ft >= BOARD_RGHT) && board[rf][ft] == EmptySquare)
+ callback(board, flags, NormalMove, rf, ff, rf, ft, closure);
+ }
break;
/* Make Dragon-Horse also do Dababba moves outside Shogi, for better disambiguation in variant Fairy */
if (SameColor(board[rf][ff], board[rt][ft])) continue;
callback(board, flags, NormalMove, rf, ff, rt, ft, closure);
}
+ if(gameInfo.variant == VariantSpartan) rookRange = 2; // in Spartan Chess restrict range to modern Dababba
goto doRook;
/* Shogi Dragon King has to continue as Ferz after Rook moves */
case WhiteMarshall:
case BlackMarshall:
m++;
+ m += (gameInfo.variant == VariantSpartan); // in Spartan Chess Chancellor is used for Dragon King.
/* Shogi Rooks are ordinary Rooks */
case SHOGI WhiteRook:
if (SameColor(board[rf][ff], board[rt][ft])) break;
callback(board, flags, NormalMove,
rf, ff, rt, ft, closure);
- if (board[rt][ft] != EmptySquare) break;
+ if (board[rt][ft] != EmptySquare || i == rookRange) break;
}
if(m==1) goto mounted;
if(m==2) goto finishSilver;
}
break;
+ Amazon:
+ /* First do Bishop,then continue like Chancellor */
+ for (rs = -1; rs <= 1; rs += 2)
+ for (fs = -1; fs <= 1; fs += 2)
+ for (i = 1;; i++) {
+ rt = rf + (i * rs);
+ ft = ff + (i * fs);
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) break;
+ if (SameColor(board[rf][ff], board[rt][ft])) break;
+ callback(board, flags, NormalMove,
+ rf, ff, rt, ft, closure);
+ if (board[rt][ft] != EmptySquare) break;
+ }
+ m++;
+ goto doRook;
+
// Use Lance as Berolina / Spartan Pawn.
case WhiteLance:
+ if(gameInfo.variant == VariantSuper) goto Amazon;
if (rf < BOARD_HEIGHT-1 && BlackPiece(board[rf + 1][ff]))
callback(board, flags,
rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotion : NormalMove,
break;
case BlackLance:
+ if(gameInfo.variant == VariantSuper) goto Amazon;
if (rf > 0 && WhitePiece(board[rf - 1][ff]))
callback(board, flags,
rf <= promoRank ? BlackPromotion : NormalMove,
/* For compatibility with ICS wild 9, we scan the board in the
order a1, a2, a3, ... b1, b2, ..., h8 to find the first king,
and we test only whether that one is in check. */
- cl.check = 0;
for (cl.fking = BOARD_LEFT+0; cl.fking < BOARD_RGHT; cl.fking++)
for (cl.rking = 0; cl.rking < BOARD_HEIGHT; cl.rking++) {
if (board[cl.rking][cl.fking] == king) {
board[i][cl.fking] == (dir>0 ? BlackWazir : WhiteWazir) )
cl.check++;
}
-
+ cl.check = 0;
GenPseudoLegal(board, flags ^ F_WHITE_ON_MOVE, CheckTestCallback, (VOIDSTAR) &cl);
- goto undo_move; /* 2-level break */
+ if(gameInfo.variant != VariantSpartan || cl.check == 0) // in Spartan Chess go on to test if other King is checked too
+ goto undo_move; /* 2-level break */
}
}
if(board[r][ft] == piece) return IllegalMove; // or there already is a Pawn in file
// should still test if we mate with this Pawn
}
+ } else if(gameInfo.variant == VariantSChess) { // only back-rank drops
+ if (rt != (piece < BlackPawn ? 0 : BOARD_HEIGHT-1)) return IllegalMove;
} else {
if( (piece == WhitePawn || piece == BlackPawn) &&
(rt == 0 || rt == BOARD_HEIGHT -1 ) )
if (cl.count > 0) {
return inCheck ? MT_CHECK : MT_NONE;
} else {
- if(gameInfo.holdingsWidth && gameInfo.variant != VariantSuper || gameInfo.variant != VariantGreat) { // drop game
+ if(gameInfo.holdingsWidth && gameInfo.variant != VariantSuper && gameInfo.variant != VariantGreat) { // drop game
int r, f, n, holdings = flags & F_WHITE_ON_MOVE ? BOARD_WIDTH-1 : 0;
for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) if(board[r][f] == EmptySquare) // all empty squares
for(n=0; n<BOARD_HEIGHT; n++) // all pieces in hand
if(board[n][holdings] != EmptySquare) {
int moveType = LegalDrop(board, flags, board[n][holdings], r, f);
- if(moveType == WhiteDrop || moveType == BlackDrop) return MT_CHECK; // we can resolve check by legal drop
+ if(moveType == WhiteDrop || moveType == BlackDrop) return (inCheck ? MT_CHECK : MT_NONE); // we have legal drop
}
}
if(gameInfo.variant == VariantSuicide) // [HGM] losers: always stalemate, since no check, but result varies
/* [HGM] in Shogi non-pawns can promote */
*outp++ = promoChar; // Don't bother to correct move type, return value is never used!
}
+ else if (gameInfo.variant != VariantSuper && promoChar &&
+ (piece == WhiteLance || piece == BlackLance) ) { // Lance sometimes represents Pawn
+ *outp++ = '=';
+ *outp++ = ToUpper(promoChar);
+ }
else if (gameInfo.variant == VariantSChess && promoChar) { // and in S-Chess we have gating
*outp++ = '/';
*outp++ = ToUpper(promoChar);