X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=moves.c;h=381b188eadb37c2671cca0c655b4ab309316d6d9;hb=deb3473452a674b82d27b03fcf7e570c1cb03841;hp=5f4b3f9670cab33d0b4a7dfe65cad41f8d34a5c2;hpb=2d0f4769e69d228d9593c574014c634706edea97;p=xboard.git diff --git a/moves.c b/moves.c index 5f4b3f9..381b188 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, 2011, 2012 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -98,7 +98,7 @@ SameColor (ChessSquare piece1, ChessSquare piece2) (int) piece2 < (int) EmptySquare); } #else -#define SameColor(piece1, piece2) (piece1 < EmptySquare && piece2 < EmptySquare && (piece1 < BlackPawn) == (piece2 < BlackPawn)) +#define SameColor(piece1, piece2) (piece1 < EmptySquare && piece2 < EmptySquare && (piece1 < BlackPawn) == (piece2 < BlackPawn) || piece1 == DarkSquare || piece2 == DarkSquare) #endif char pieceToChar[] = { @@ -520,7 +520,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR 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 SHOGI WhiteDragon: case SHOGI BlackDragon: @@ -573,7 +573,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure, /* Shogi Pawn and Silver General: first the Pawn move, */ /* then the General continues like a Ferz */ case WhiteMan: - if(gameInfo.variant != VariantMakruk) goto commoner; + if(gameInfo.variant != VariantMakruk && gameInfo.variant != VariantASEAN) goto commoner; case SHOGI WhitePawn: case SHOGI WhiteFerz: if (rf < BOARD_HEIGHT-1 && @@ -584,7 +584,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure, break; case BlackMan: - if(gameInfo.variant != VariantMakruk) goto commoner; + if(gameInfo.variant != VariantMakruk && gameInfo.variant != VariantASEAN) goto commoner; case SHOGI BlackPawn: case SHOGI BlackFerz: if (rf > 0 && @@ -673,14 +673,14 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure, rf, ff, rf + 1, ff, closure); for (s = -1; s <= 1; s += 2) { if (rf < BOARD_HEIGHT-1 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT && board[rf + 1][ff + s] == EmptySquare) - callback(board, flags, + callback(board, flags, rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotion : NormalMove, rf, ff, rf + 1, ff + s, closure); if (rf == 1 && ff + 2*s >= BOARD_LEFT && ff + 2*s < BOARD_RGHT && board[3][ff + 2*s] == EmptySquare ) callback(board, flags, NormalMove, rf, ff, 3, ff + 2*s, closure); } break; - + case BlackLance: if(gameInfo.variant == VariantSuper) goto Amazon; if (rf > 0 && WhitePiece(board[rf - 1][ff])) @@ -689,7 +689,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure, rf, ff, rf - 1, ff, closure); for (s = -1; s <= 1; s += 2) { if (rf > 0 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT && board[rf - 1][ff + s] == EmptySquare) - callback(board, flags, + callback(board, flags, rf <= promoRank ? BlackPromotion : NormalMove, rf, ff, rf - 1, ff + s, closure); if (rf == BOARD_HEIGHT-2 && ff + 2*s >= BOARD_LEFT && ff + 2*s < BOARD_RGHT && board[rf-2][ff + 2*s] == EmptySquare ) @@ -721,7 +721,7 @@ extern void GenLegalCallback P((Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VOIDSTAR closure)); -void +void GenLegalCallback (Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VOIDSTAR closure) { register GenLegalClosure *cl = (GenLegalClosure *) closure; @@ -1104,7 +1104,7 @@ LegalityTest (Board board, int flags, int rf, int ff, int rt, int ft, int promoC if(quickFlag) flags = flags & ~1 | quickFlag & 1; // [HGM] speed: in quick mode quickFlag specifies side-to-move. if(rf == DROP_RANK) return LegalDrop(board, flags, ff, rt, ft); piece = filterPiece = board[rf][ff]; - if(PieceToChar(piece) == '~') filterPiece = DEMOTED piece; + if(PieceToChar(piece) == '~') filterPiece = DEMOTED piece; /* [HGM] Cobra and Falcon are wildcard pieces; consider all their moves legal */ /* (perhaps we should disallow moves that obviously leave us in check?) */ @@ -1136,7 +1136,7 @@ LegalityTest (Board board, int flags, int rf, int ff, int rt, int ft, int promoC if(board[BOARD_HEIGHT-1-PieceToNumber(CharToPiece(ToLower(promoChar)))][1] == 0) return ImpossibleMove; } } else - if(gameInfo.variant == VariantShogi) { + if(IS_SHOGI(gameInfo.variant)) { /* [HGM] Shogi promotions. '=' means defer */ if(rf != DROP_RANK && cl.kind == NormalMove) { ChessSquare piece = board[rf][ff]; @@ -1151,7 +1151,7 @@ if(appData.debugMode)fprintf(debugFP,"SHOGI promoChar = %c\n", promoChar ? promo return CharToPiece(promoChar) == EmptySquare ? ImpossibleMove : IllegalMove; else if(flags & F_WHITE_ON_MOVE) { if( (int) piece < (int) WhiteWazir && - (rf >= BOARD_HEIGHT*2/3 || rt >= BOARD_HEIGHT*2/3) ) { + (rf >= BOARD_HEIGHT - BOARD_HEIGHT/3 || rt >= BOARD_HEIGHT - BOARD_HEIGHT/3) ) { if( (piece == WhitePawn || piece == WhiteQueen) && rt > BOARD_HEIGHT-2 || piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */ cl.kind = promoChar == '=' ? IllegalMove : WhitePromotion; @@ -1264,7 +1264,7 @@ MateTest (Board board, int flags) else if(gameInfo.variant == VariantGiveaway) return MT_STEALMATE; // no check exists, stalemated = win return inCheck ? MT_CHECKMATE - : (gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj) ? + : (gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj || gameInfo.variant == VariantShogi) ? MT_STAINMATE : MT_STALEMATE; } } @@ -1367,6 +1367,9 @@ Disambiguate (Board board, int flags, DisambiguateClosure *closure) if(board[BOARD_HEIGHT-1-PieceToNumber(CharToPiece(ToLower(c)))][1] == 0) closure->kind = ImpossibleMove; } } else + if(gameInfo.variant == VariantChu) { + if(c == '+') closure->kind = (flags & F_WHITE_ON_MOVE ? WhitePromotion : BlackPromotion); // for now, accept any + } else if(gameInfo.variant == VariantShogi) { /* [HGM] Shogi promotions. On input, '=' means defer, '+' promote. Afterwards, c is set to '+' for promotions, NULL other */ if(closure->rfIn != DROP_RANK && closure->kind == NormalMove) { @@ -1383,7 +1386,7 @@ Disambiguate (Board board, int flags, DisambiguateClosure *closure) piece == WhiteKnight && closure->rt > BOARD_HEIGHT-3) /* promotion mandatory */ closure->kind = c == '=' ? IllegalMove : WhitePromotion; else /* promotion optional, default is defer */ - closure->kind = c == '+' ? WhitePromotion : WhiteNonPromotion; + closure->kind = c == '+' ? WhitePromotion : WhiteNonPromotion; } else closure->kind = c == '+' ? IllegalMove : NormalMove; } else { if( (int) piece < (int) BlackWazir && (closure->rf < BOARD_HEIGHT/3 || closure->rt < BOARD_HEIGHT/3) ) { @@ -1400,7 +1403,8 @@ Disambiguate (Board board, int flags, DisambiguateClosure *closure) } else if (closure->kind == WhitePromotion || closure->kind == BlackPromotion) { if(c == NULLCHAR) { // missing promoChar on mandatory promotion; use default for variant - if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || + gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) c = PieceToChar(BlackFerz); else if(gameInfo.variant == VariantGreat) c = PieceToChar(BlackMan); @@ -1527,7 +1531,7 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p /* Use promotion suffix style "=Q" */ *outp = NULLCHAR; if (promoChar != NULLCHAR) { - if(gameInfo.variant == VariantShogi) { + if(IS_SHOGI(gameInfo.variant)) { /* [HGM] ... but not in Shogi! */ *outp++ = promoChar == '=' ? '=' : '+'; } else { @@ -1625,11 +1629,11 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p if(rt+ONE <= '9') *outp++ = rt + ONE; else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; } - if (gameInfo.variant == VariantShogi) { + if (IS_SHOGI(gameInfo.variant)) { /* [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 && + else if (gameInfo.variant != VariantSuper && promoChar && (piece == WhiteLance || piece == BlackLance) ) { // Lance sometimes represents Pawn *outp++ = '='; *outp++ = ToUpper(promoChar); @@ -1640,7 +1644,7 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p } *outp = NULLCHAR; return cl.kind; - + case EmptySquare: /* Moving a nonexistent piece */ break;