X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=moves.c;h=f9302318911dc7db6e0dfcd7b37b4ecc5b2dd073;hb=cde66749ec8a0b3c823bbc7aa3818b86821514ec;hp=6fa6693611b000bec7ea909949517235b0124582;hpb=020fc338d749be0f8f49d133911a6c33d2eb56a1;p=xboard.git diff --git a/moves.c b/moves.c index 6fa6693..f930231 100644 --- a/moves.c +++ b/moves.c @@ -5,7 +5,7 @@ * 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 * @@ -126,6 +126,7 @@ ChessSquare CharToPiece(c) 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++) @@ -182,6 +183,7 @@ void GenPseudoLegal(board, flags, callback, closure) 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; @@ -194,7 +196,7 @@ void GenPseudoLegal(board, flags, callback, closure) 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...) */ @@ -418,7 +420,8 @@ void GenPseudoLegal(board, flags, callback, closure) && !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 + || 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) @@ -426,6 +429,12 @@ void GenPseudoLegal(board, flags, callback, closure) 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 */ @@ -507,6 +516,7 @@ void GenPseudoLegal(board, flags, callback, closure) 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 */ @@ -518,6 +528,7 @@ void GenPseudoLegal(board, flags, callback, closure) 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: @@ -534,7 +545,7 @@ void GenPseudoLegal(board, flags, callback, closure) 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; @@ -714,10 +725,15 @@ void GenLegalCallback(board, flags, kind, rf, ff, rt, ft, closure) { 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) { @@ -985,10 +1001,10 @@ int CheckTest(board, flags, rf, ff, rt, ft, enPassant) /* 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) { + cl.check = 0; if(gameInfo.variant == VariantXiangqi) { /* [HGM] In Xiangqi opposing Kings means check as well */ int i, dir; @@ -999,9 +1015,9 @@ int CheckTest(board, flags, rf, ff, rt, ft, enPassant) board[i][cl.fking] == (dir>0 ? BlackWazir : WhiteWazir) ) cl.check++; } - 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 */ } } @@ -1043,6 +1059,8 @@ if(appData.debugMode) fprintf(debugFP, "LegalDrop: %d @ %d,%d)\n", piece, ft, rt 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 ) ) @@ -1154,8 +1172,23 @@ if(appData.debugMode)fprintf(debugFP,"SHOGI promoChar = %c\n", promoChar ? promo 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 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