* Massachusetts.
*
* Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
*
* Enhancements Copyright 2005 Alessandro Scotti
*
int c;
{
int i;
+ if(c == '.') return EmptySquare;
for(i=0; i< (int) EmptySquare; i++)
if(pieceNickName[i] == c) return (ChessSquare) i;
for(i=0; i< (int) EmptySquare; i++)
if(gameInfo.variant == VariantShogi)
piece = (ChessSquare) ( SHOGI piece );
- switch (piece) {
+ switch ((int)piece) {
/* case EmptySquare: [HGM] this is nonsense, and conflicts with Shogi cases */
default:
/* can't happen ([HGM] except for faries...) */
&& !SameColor(board[rf][ff], board[rt][ft]))
callback(board, flags, NormalMove,
rf, ff, rt, ft, closure);
- if(gameInfo.variant == VariantShatranj && gameInfo.variant == VariantCourier) continue; // classical Alfil
+ if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier
+ || gameInfo.variant == VariantXiangqi) 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)
{
register GenLegalClosure *cl = (GenLegalClosure *) closure;
- if (!(flags & F_IGNORE_CHECK) &&
- CheckTest(board, flags, rf, ff, rt, ft,
+ if (!(flags & F_IGNORE_CHECK) ) {
+ int check, promo = (gameInfo.variant == VariantSpartan && kind == BlackPromotion);
+ if(promo) board[rf][ff] = BlackKing; // [HGM] spartan: promote to King before check-test
+ check = CheckTest(board, flags, rf, ff, rt, ft,
kind == WhiteCapturesEnPassant ||
- kind == BlackCapturesEnPassant)) return;
+ kind == BlackCapturesEnPassant);
+ if(promo) board[rf][ff] = BlackLance;
+ if(check) return;
+ }
if (flags & F_ATOMIC_CAPTURE) {
if (board[rt][ft] != EmptySquare ||
kind == WhiteCapturesEnPassant || kind == BlackCapturesEnPassant) {
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) {
+ cl.check = 0;
if(gameInfo.variant == VariantXiangqi) {
/* [HGM] In Xiangqi opposing Kings means check as well */
int i, dir;
board[i][cl.fking] == (dir>0 ? BlackWazir : WhiteWazir) )
cl.check++;
}
- cl.check = 0;
GenPseudoLegal(board, flags ^ F_WHITE_ON_MOVE, CheckTestCallback, (VOIDSTAR) &cl);
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 (promoChar != NULLCHAR) {
if(promoChar == '=') cl.kind = IllegalMove; else // [HGM] shogi: no deferred promotion outside Shogi
if (cl.kind == WhitePromotion || cl.kind == BlackPromotion) {
- if(CharToPiece(flags & F_WHITE_ON_MOVE ? ToUpper(promoChar) : ToLower(promoChar)) == EmptySquare)
+ ChessSquare piece = CharToPiece(flags & F_WHITE_ON_MOVE ? ToUpper(promoChar) : ToLower(promoChar));
+ if(piece == EmptySquare)
cl.kind = ImpossibleMove; // non-existing piece
+ if(gameInfo.variant == VariantSpartan && cl.kind == BlackPromotion ) {
+ if(promoChar != PieceToChar(BlackKing)) {
+ if(CheckTest(board, flags, rf, ff, rt, ft, FALSE)) cl.kind = IllegalMove; // [HGM] spartan: only promotion to King was possible
+ if(piece == BlackLance) cl.kind = ImpossibleMove;
+ } else { // promotion to King allowed only if we do not haave two yet
+ int r, f, kings = 0;
+ for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) kings += (board[r][f] == BlackKing);
+ if(kings == 2) cl.kind = IllegalMove;
+ }
+ } else if(piece == WhitePawn || piece == BlackPawn) cl.kind = ImpossibleMove; // cannot stay Pawn in any variant
+ else if((piece == WhiteUnicorn || piece == BlackUnicorn) && gameInfo.variant == VariantKnightmate)
+ cl.kind = IllegalMove; // promotion to Royal Knight not allowed
+ else if((piece == WhiteKing || piece == BlackKing) && gameInfo.variant != VariantSuicide && gameInfo.variant != VariantGiveaway)
+ cl.kind = IllegalMove; // promotion to King usually not allowed
} else {
cl.kind = IllegalMove;
}
int preyStackPointer, chaseStackPointer;
struct {
-char rf, ff, rt, ft;
+unsigned char rf, ff, rt, ft;
} chaseStack[100];
struct {
-char rank, file;
+unsigned char rank, file;
} preyStack[100];