X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=moves.c;h=58cbfc008c47f8f794aa83acc0ebb1fe348d2bbf;hb=998b7c7246b5f2e96db31bbbd3c7e760849c2290;hp=deac69fb1415c05507a52ed2324db0ca9c1f0fb4;hpb=0efdc4c5ef60cf4c15e9dddf3658d2115e4d5d93;p=xboard.git diff --git a/moves.c b/moves.c index deac69f..58cbfc0 100644 --- a/moves.c +++ b/moves.c @@ -117,89 +117,26 @@ ChessSquare PromoPiece(moveType) return WhiteKing; case BlackPromotionKing: return BlackKing; -#ifdef FAIRY case WhitePromotionChancellor: return WhiteMarshall; case BlackPromotionChancellor: return BlackMarshall; case WhitePromotionArchbishop: - return WhiteCardinal; + return WhiteAngel; case BlackPromotionArchbishop: - return BlackCardinal; -#endif - } -} - -ChessMove PromoCharToMoveType(whiteOnMove, promoChar) - int whiteOnMove; - int promoChar; -{ - if (whiteOnMove) { - switch (promoChar) { - case 'n': - case 'N': - return WhitePromotionKnight; - case 'b': - case 'B': - return WhitePromotionBishop; - case 'r': - case 'R': - return WhitePromotionRook; -#ifdef FAIRY - case 'a': - case 'A': - return WhitePromotionArchbishop; - case 'c': - case 'C': - return WhitePromotionChancellor; -#endif - case 'q': - case 'Q': - return WhitePromotionQueen; - case 'k': - case 'K': - return WhitePromotionKing; - case NULLCHAR: - default: - return NormalMove; - } - } else { - switch (promoChar) { - case 'n': - case 'N': - return BlackPromotionKnight; - case 'b': - case 'B': - return BlackPromotionBishop; - case 'r': - case 'R': - return BlackPromotionRook; -#ifdef FAIRY - case 'a': - case 'A': - return BlackPromotionArchbishop; - case 'c': - case 'C': - return BlackPromotionChancellor; -#endif - case 'q': - case 'Q': - return BlackPromotionQueen; - case 'k': - case 'K': - return BlackPromotionKing; - case NULLCHAR: - default: - return NormalMove; - } + return BlackAngel; + case WhitePromotionCentaur: + return WhiteSilver; + case BlackPromotionCentaur: + return BlackSilver; } } char pieceToChar[] = { 'P', 'N', 'B', 'R', 'Q', 'F', 'E', 'A', 'C', 'W', 'M', - 'O', 'H', 'I', 'J', 'G', 'D', 'V', 'S', 'L', 'U', 'K', + 'O', 'H', 'I', 'J', 'G', 'D', 'V', 'L', 's', 'U', 'K', 'p', 'n', 'b', 'r', 'q', 'f', 'e', 'a', 'c', 'w', 'm', - 'o', 'h', 'i', 'j', 'g', 'd', 'v', 's', 'l', 'u', 'k', + 'o', 'h', 'i', 'j', 'g', 'd', 'v', 'l', 's', 'u', 'k', 'x' }; char PieceToChar(p) @@ -228,6 +165,52 @@ ChessSquare CharToPiece(c) return EmptySquare; } +ChessMove PromoCharToMoveType(whiteOnMove, promoChar) + int whiteOnMove; + int promoChar; +{ /* [HGM] made dependent on CharToPiece to alow alternate piece letters */ + ChessSquare piece = CharToPiece(whiteOnMove ? ToUpper(promoChar) : ToLower(promoChar) ); + if(promoChar == NULLCHAR) return NormalMove; + + switch(piece) { + case WhiteQueen: + return WhitePromotionQueen; + case WhiteRook: + return WhitePromotionRook; + case WhiteBishop: + return WhitePromotionBishop; + case WhiteKnight: + return WhitePromotionKnight; + case WhiteKing: + return WhitePromotionKing; + case WhiteAngel: + return WhitePromotionArchbishop; + case WhiteMarshall: + return WhitePromotionChancellor; + case WhiteSilver: + return WhitePromotionCentaur; + case BlackQueen: + return BlackPromotionQueen; + case BlackRook: + return BlackPromotionRook; + case BlackBishop: + return BlackPromotionBishop; + case BlackKnight: + return BlackPromotionKnight; + case BlackKing: + return BlackPromotionKing; + case BlackAngel: + return BlackPromotionArchbishop; + case BlackMarshall: + return BlackPromotionChancellor; + case BlackSilver: + return BlackPromotionCentaur; + default: + // not all promotion implemented yet! Take Queen for those we don't know. + return (whiteOnMove ? WhitePromotionQueen : BlackPromotionQueen); + } +} + void CopyBoard(to, from) Board to, from; { @@ -595,7 +578,7 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) if (board[rt][ft] != EmptySquare) break; } if(m==1) goto mounted; - if(m==2) goto walking; + if(m==2) goto finishGold; break; case WhiteQueen: @@ -650,6 +633,9 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) } break; + case WhiteSilver: + case BlackSilver: + m++; // [HGM] superchess: use for Centaur case WhiteMan: case BlackMan: case SHOGI WhiteKing: @@ -667,6 +653,7 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) callback(board, flags, NormalMove, rf, ff, rt, ft, closure); } + if(m==1) goto mounted; break; case WhiteNightrider: @@ -783,11 +770,12 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) (ignoreCheck || (!CheckTest(board, flags, 0, ff, 0, ff + 1, FALSE) && !CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-3, FALSE) && + (gameInfo.variant != VariantJanus || !CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-2, FALSE)) && !CheckTest(board, flags, 0, ff, 0, ff + 2, FALSE)))) { callback(board, flags, ff==BOARD_WIDTH>>1 ? WhiteKingSideCastle : WhiteKingSideCastleWild, - 0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2), closure); + 0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2) + (gameInfo.variant == VariantJanus), closure); } if ((flags & F_WHITE_ON_MOVE) && (flags & F_WHITE_QCASTLE_OK) && @@ -801,7 +789,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) ( castlingRights[2] == ff || castlingRights[6] == ff ) && (ignoreCheck || (!CheckTest(board, flags, 0, ff, 0, ff - 1, FALSE) && - !CheckTest(board, flags, 0, ff, 0, BOARD_LEFT+3, FALSE) && + !CheckTest(board, flags, 0, ff, 0, BOARD_LEFT+3, FALSE) && !CheckTest(board, flags, 0, ff, 0, ff - 2, FALSE)))) { callback(board, flags, @@ -821,11 +809,12 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) (ignoreCheck || (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 1, FALSE) && !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-3, FALSE) && + (gameInfo.variant != VariantJanus || !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-2, FALSE)) && !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 2, FALSE)))) { callback(board, flags, ff==BOARD_WIDTH>>1 ? BlackKingSideCastle : BlackKingSideCastleWild, - BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2), closure); + BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2) + (gameInfo.variant == VariantJanus), closure); } if (!(flags & F_WHITE_ON_MOVE) && (flags & F_BLACK_QCASTLE_OK) && @@ -839,7 +828,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) ( castlingRights[5] == ff || castlingRights[7] == ff ) && (ignoreCheck || (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 1, FALSE) && - !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_LEFT+3, FALSE) && + !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_LEFT+3, FALSE) && !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 2, FALSE)))) { callback(board, flags, @@ -856,7 +845,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) if ((flags & F_WHITE_ON_MOVE) != 0) { ff = castlingRights[2]; /* King file if we have any rights */ - if(ff > 0) { + if(ff > 0 && board[0][ff] == WhiteKing) { if (appData.debugMode) { fprintf(debugFP, "FRC castling, %d %d %d %d %d %d\n", castlingRights[0],castlingRights[1],ff,castlingRights[3],castlingRights[4],castlingRights[5]); @@ -869,7 +858,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) if(k != ft && board[0][k] != EmptySquare) ft = -1; for(k=left; k= 0; k++) /* then if not checked */ if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1; - if(ft >= 0) + if(ft >= 0 && board[0][ft] == WhiteRook) callback(board, flags, WhiteHSideCastleFR, 0, ff, 0, ft, closure); ft = castlingRights[1]; /* Rook file if we have A-side rights */ @@ -881,13 +870,12 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) if(ff > BOARD_LEFT+2) for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */ if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1; - - if(ft >= 0) + if(ft >= 0 && board[0][ft] == WhiteRook) callback(board, flags, WhiteASideCastleFR, 0, ff, 0, ft, closure); } } else { ff = castlingRights[5]; /* King file if we have any rights */ - if(ff > 0) { + if(ff > 0 && board[BOARD_HEIGHT-1][ff] == BlackKing) { ft = castlingRights[3]; /* Rook file if we have H-side rights */ left = ff+1; right = BOARD_RGHT-2; @@ -896,7 +884,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1; for(k=left; k= 0; k++) /* then if not checked */ if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1; - if(ft >= 0) + if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook) callback(board, flags, BlackHSideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure); ft = castlingRights[4]; /* Rook file if we have A-side rights */ @@ -908,8 +896,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) if(ff > BOARD_LEFT+2) for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */ if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1; - - if(ft >= 0) + if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook) callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure); } } @@ -1144,7 +1131,7 @@ int MateTest(board, flags, epfile, castlingRights) if (cl.count > 0) { return inCheck ? MT_CHECK : MT_NONE; } else { - return inCheck || gameInfo.variant == VariantXiangqi ? + return inCheck || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj ? MT_CHECKMATE : MT_STALEMATE; } } @@ -1191,6 +1178,11 @@ void Disambiguate(board, flags, epfile, closure) closure->count = 0; closure->rf = closure->ff = closure->rt = closure->ft = 0; closure->kind = ImpossibleMove; + if (appData.debugMode) { + fprintf(debugFP, "Disambiguate in: %d(%d,%d)-(%d,%d) = %d (%c)\n", + closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn, + closure->promoCharIn, closure->promoCharIn >= ' ' ? closure->promoCharIn : '-'); + } GenLegal(board, flags, epfile, initialRights, DisambiguateCallback, (VOIDSTAR) closure); if (closure->count == 0) { /* See if it's an illegal move due to check */ @@ -1199,15 +1191,17 @@ void Disambiguate(board, flags, epfile, closure) (VOIDSTAR) closure); if (closure->count == 0) { /* No, it's not even that */ + if (appData.debugMode) { int i, j; + for(i=BOARD_HEIGHT-1; i>=0; i--) { + for(j=0; jpieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn, - closure->promoCharIn,closure->promoCharIn); - } if(gameInfo.variant == VariantShogi) { /* [HGM] Shogi promotions. '=' means defer */ if(closure->rfIn != DROP_RANK && closure->kind == NormalMove) { @@ -1272,7 +1266,7 @@ void Disambiguate(board, flags, epfile, closure) #endif /* [HGM] returns 'q' for optional promotion, 'n' for mandatory */ if(closure->promoCharIn != '=') - closure->promoChar = ToLower(PieceToChar(PromoPiece(closure->kind))); + closure->promoChar = ToLower(closure->promoCharIn); else closure->promoChar = '='; if (closure->promoChar == 'x') closure->promoChar = NULLCHAR; if (closure->count > 1) { @@ -1287,10 +1281,11 @@ void Disambiguate(board, flags, epfile, closure) } if(closure->kind == IllegalMove) /* [HGM] might be a variant we don't understand, pass on promotion info */ - closure->promoChar = closure->promoCharIn; + closure->promoChar = ToLower(closure->promoCharIn); if (appData.debugMode) { fprintf(debugFP, "Disambiguate out: %d(%d,%d)-(%d,%d) = %d (%c)\n", - closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar,closure->promoChar); + closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar, + closure->promoChar >= ' ' ? closure->promoChar:'-'); } } @@ -1374,7 +1369,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, if(PieceToChar(piece)=='~') piece = (ChessSquare)(DEMOTED piece); if (appData.debugMode) - fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar ); + fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar >= ' ' ? promoChar : '-'); switch (piece) { case WhitePawn: case BlackPawn: @@ -1406,7 +1401,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, /* Use promotion suffix style "=Q" */ *outp = NULLCHAR; if (appData.debugMode) - fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar); + fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar >= ' ' ? promoChar : '-'); if (promoChar != NULLCHAR) { if(gameInfo.variant == VariantShogi) { /* [HGM] ... but not in Shogi! */ @@ -1549,8 +1544,6 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, /* [HGM] Always long notation for fairies we don't know */ case WhiteFalcon: case BlackFalcon: - case WhiteSilver: - case BlackSilver: case WhiteLance: case BlackLance: case WhiteGrasshopper: