X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=8aae7b4489b4df79a5803758ff78b0755c65ccad;hb=3536ccf4ea73a0157ef01ae42c72e5448543eb39;hp=43df74d7cc252ad51f4cb1e78b5bcb2cff402cb6;hpb=893ed0aaac95bf06a8b067bc179076c134ab044d;p=xboard.git diff --git a/backend.c b/backend.c index 43df74d..8aae7b4 100644 --- a/backend.c +++ b/backend.c @@ -5399,8 +5399,8 @@ Sweep (int step) if(step && !(toggleFlag && Partner(&promoSweep))) promoSweep -= step; if(promoSweep == EmptySquare) promoSweep = BlackPawn; // wrap else if((int)promoSweep == -1) promoSweep = WhiteKing; - else if(promoSweep == BlackPawn && step < 0) promoSweep = WhitePawn; - else if(promoSweep == WhiteKing && step > 0) promoSweep = BlackKing; + else if(promoSweep == BlackPawn && step < 0 && !toggleFlag) promoSweep = WhitePawn; + else if(promoSweep == WhiteKing && step > 0 && !toggleFlag) promoSweep = BlackKing; if(!step) step = -1; } while(PieceToChar(promoSweep) == '.' || PieceToChar(promoSweep) == '~' || promoSweep == pawn || !toggleFlag && PieceToChar(promoSweep) == '+' || // skip promoted versions of other @@ -5527,7 +5527,12 @@ ParseOneMove (char *move, int moveNum, ChessMove *moveType, int *fromX, int *fro case BlackASideCastleFR: /* End of code added by Tord */ case IllegalMove: /* bug or odd chess variant */ - if(currentMoveString[1] == '@') goto drop; // illegal drop + if(currentMoveString[1] == '@') { // illegal drop + *fromX = WhiteOnMove(moveNum) ? + (int) CharToPiece(ToUpper(currentMoveString[0])) : + (int) CharToPiece(ToLower(currentMoveString[0])); + goto drop; + } *fromX = currentMoveString[0] - AAA; *fromY = currentMoveString[1] - ONE; *toX = currentMoveString[2] - AAA; @@ -5551,10 +5556,10 @@ ParseOneMove (char *move, int moveNum, ChessMove *moveType, int *fromX, int *fro case WhiteDrop: case BlackDrop: - drop: *fromX = *moveType == WhiteDrop ? (int) CharToPiece(ToUpper(currentMoveString[0])) : (int) CharToPiece(ToLower(currentMoveString[0])); + drop: *fromY = DROP_RANK; *toX = currentMoveString[2] - AAA; *toY = currentMoveString[3] - ONE; @@ -6561,7 +6566,7 @@ HasPromotionChoice (int fromX, int fromY, int toX, int toY, char *promoChoice, i promotionZoneSize = BOARD_HEIGHT/3; highestPromotingPiece = (p >= WhiteLion || PieceToChar(piece + 22) == '.') ? WhitePawn : WhiteLion; } else if(gameInfo.variant == VariantShogi) { - promotionZoneSize = BOARD_HEIGHT/3; + promotionZoneSize = BOARD_HEIGHT/3 +(BOARD_HEIGHT == 8); highestPromotingPiece = (int)WhiteAlfil; } else if(gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess) { promotionZoneSize = 3; @@ -7519,7 +7524,7 @@ printf("to click %d,%d\n",x,y); toP = boards[currentMove][y][x]; frc = appData.fischerCastling || gameInfo.variant == VariantSChess; if( (killX < 0 || x != fromX || y != fromY) && // [HGM] lion: do not interpret igui as deselect! - legal[y][x] == 0 && // if engine told we can move to here, do it even if own piece + marker[y][x] == 0 && // if engine told we can move to here, do it even if own piece ((WhitePawn <= fromP && fromP <= WhiteKing && WhitePawn <= toP && toP <= WhiteKing && !(fromP == WhiteKing && toP == WhiteRook && frc) && @@ -7551,7 +7556,7 @@ printf("to click %d,%d\n",x,y); else gatingPiece = doubleClick ? fromP : EmptySquare; fromX = x; fromY = y; dragging = 1; - ReportClick("lift", x, y); + if(!second) ReportClick("lift", x, y); MarkTargetSquares(0); DragPieceBegin(xPix, yPix, FALSE); if(appData.sweepSelect && CanPromote(piece = boards[currentMove][y][x], y)) { @@ -7574,7 +7579,7 @@ printf("A type=%d\n",clickType); return; } - if (clickType == Release && x == fromX && y == fromY && killX < 0) { + if (clickType == Release && x == fromX && y == fromY && killX < 0 && !sweepSelecting) { DragPieceEnd(xPix, yPix); dragging = 0; if(clearFlag) { // a deferred attempt to click-click move an empty square on top of a piece @@ -7588,10 +7593,9 @@ printf("A type=%d\n",clickType); /* Undo animation damage if any */ DrawPosition(FALSE, NULL); } - if (second || sweepSelecting) { + if (second) { /* Second up/down in same square; just abort move */ - if(sweepSelecting) DrawPosition(FALSE, boards[currentMove]); - second = sweepSelecting = 0; + second = 0; fromX = fromY = -1; gatingPiece = EmptySquare; MarkTargetSquares(1); @@ -7726,7 +7730,9 @@ printf("(%d,%d)-(%d,%d) %d %d\n",fromX,fromY,toX,toY,x,y); if(gatingPiece != EmptySquare && gameInfo.variant == VariantSChess) promoChoice = ToLower(PieceToChar(gatingPiece)); - if (HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, appData.sweepSelect)) { + if(legal[toY][toX] == 2) promoChoice = ToLower(PieceToChar(defaultPromoChoice)); // highlight-induced promotion + + if (legal[toY][toX] == 2 && !appData.sweepSelect || HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, appData.sweepSelect)) { SetHighlights(fromX, fromY, toX, toY); MarkTargetSquares(1); if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat || gameInfo.variant == VariantGrand) { @@ -10011,8 +10017,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) if(gameInfo.variant == VariantKnightmate) king += (int) WhiteUnicorn - (int) WhiteKing; - if(piece != WhiteKing && piece != BlackKing && pieceDesc[piece] && killX >= 0 && strchr(pieceDesc[piece], 'O') // Betza castling-enabled - && (piece < BlackPawn ? killed < BlackPawn : killed >= BlackPawn)) { // and captures own + if(pieceDesc[piece] && killX >= 0 && strchr(pieceDesc[piece], 'O') // Betza castling-enabled + && (piece < BlackPawn ? killed < BlackPawn : killed >= BlackPawn)) { // and tramples own board[toY][toX] = piece; board[fromY][fromX] = EmptySquare; board[toY][toX + (killX < fromX ? 1 : -1)] = killed; board[EP_STATUS] = EP_NONE; // capture was fake! @@ -10044,19 +10050,19 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX > fromX+1) { + for(rookX=fromX+1; board[toY][rookX] == EmptySquare && rookX < BOARD_RGHT-1; rookX++); // castle with nearest piece + board[fromY][toX-1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - for(rookX=BOARD_RGHT-1; board[toY][rookX] == DarkSquare && rookX > toX + 1; rookX--); - board[toY][toX-1] = board[fromY][rookX]; - board[fromY][rookX] = EmptySquare; } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX < fromX-1) { + for(rookX=fromX-1; board[toY][rookX] == EmptySquare && rookX > 0; rookX--); // castle with nearest piece + board[fromY][toX+1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - for(rookX=BOARD_LEFT; board[toY][rookX] == DarkSquare && rookX < toX - 1; rookX++); - board[toY][toX+1] = board[fromY][rookX]; - board[fromY][rookX] = EmptySquare; } else if ((board[fromY][fromX] == WhitePawn && gameInfo.variant != VariantXiangqi || board[fromY][fromX] == WhiteLance && gameInfo.variant != VariantSuper && gameInfo.variant != VariantChu) && toY >= BOARD_HEIGHT-promoRank && promoChar // defaulting to Q is done elsewhere @@ -10095,19 +10101,19 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX > fromX+1) { + for(rookX=toX+1; board[toY][rookX] == EmptySquare && rookX < BOARD_RGHT - 1; rookX++); + board[fromY][toX-1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - for(rookX=BOARD_RGHT-1; board[toY][rookX] == DarkSquare && rookX > toX + 1; rookX--); - board[toY][toX-1] = board[fromY][rookX]; - board[fromY][rookX] = EmptySquare; } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX < fromX-1) { + for(rookX=toX-1; board[toY][rookX] == EmptySquare && rookX > 0; rookX--); + board[fromY][toX+1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - for(rookX=BOARD_LEFT; board[toY][rookX] == DarkSquare && rookX < toX - 1; rookX++); - board[toY][toX+1] = board[fromY][rookX]; - board[fromY][rookX] = EmptySquare; } else if (fromY == 7 && fromX == 3 && board[fromY][fromX] == BlackKing && toY == 7 && toX == 5) { @@ -12069,8 +12075,13 @@ LoadGameOneMove (ChessMove readAhead) if (appData.debugMode) fprintf(debugFP, "Parsed %s into IllegalMove %s\n", yy_text, currentMoveString); - fromX = currentMoveString[0] - AAA; - fromY = currentMoveString[1] - ONE; + if(currentMoveString[1] == '@') { + fromX = CharToPiece(WhiteOnMove(currentMove) ? ToUpper(currentMoveString[0]) : ToLower(currentMoveString[0])); + fromY = DROP_RANK; + } else { + fromX = currentMoveString[0] - AAA; + fromY = currentMoveString[1] - ONE; + } toX = currentMoveString[2] - AAA; toY = currentMoveString[3] - ONE; promoChar = currentMoveString[4]; @@ -17999,7 +18010,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) Boolean ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) { - int i, j, k, w=0, subst=0, shuffle=0; + int i, j, k, w=0, subst=0, shuffle=0, wKingRank = -1, bKingRank = -1; char *p, c; int emptycount, virgin[BOARD_FILES]; ChessSquare piece; @@ -18064,6 +18075,8 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) p++; } board[i][(j++)+gameInfo.holdingsWidth] = piece; + if(piece == WhiteKing) wKingRank = i; + if(piece == BlackKing) bKingRank = i; } else { return FALSE; } @@ -18163,6 +18176,13 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) /* [HGM] We NO LONGER ignore the rest of the FEN notation */ /* return the extra info in global variiables */ + while(*p==' ') p++; + + if(!isdigit(*p) && *p != '-') { // we seem to have castling rights. Make sure they are on the rank the King actually is. + if(wKingRank >= 0) for(i=0; i<3; i++) castlingRank[i] = wKingRank; + if(bKingRank >= 0) for(i=3; i<6; i++) castlingRank[i] = bKingRank; + } + /* set defaults in case FEN is incomplete */ board[EP_STATUS] = EP_UNKNOWN; for(i=0; i> 1; // for these variant scanning fails @@ -18207,7 +18226,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) && board[BOARD_HEIGHT-1][blackKingFile] != BlackKing) blackKingFile = NoRights; switch(c) { case'K': - for(i=BOARD_RGHT-1; board[0][i]!=WhiteRook && i>whiteKingFile; i--); + for(i=BOARD_RGHT-1; board[castlingRank[2]][i]!=WhiteRook && i>whiteKingFile; i--); board[CASTLING][0] = i != whiteKingFile ? i : NoRights; board[CASTLING][2] = whiteKingFile; if(board[CASTLING][0] != NoRights) virgin[board[CASTLING][0]] |= VIRGIN_W; @@ -18215,7 +18234,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) if(whiteKingFile != BOARD_WIDTH>>1|| i != BOARD_RGHT-1) fischer = 1; break; case'Q': - for(i=BOARD_LEFT; i>1|| i != BOARD_LEFT) fischer = 1; break; case'k': - for(i=BOARD_RGHT-1; board[BOARD_HEIGHT-1][i]!=BlackRook && i>blackKingFile; i--); + for(i=BOARD_RGHT-1; board[castlingRank[5]][i]!=BlackRook && i>blackKingFile; i--); board[CASTLING][3] = i != blackKingFile ? i : NoRights; board[CASTLING][5] = blackKingFile; if(board[CASTLING][3] != NoRights) virgin[board[CASTLING][3]] |= VIRGIN_B; @@ -18231,7 +18250,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) if(blackKingFile != BOARD_WIDTH>>1|| i != BOARD_RGHT-1) fischer = 1; break; case'q': - for(i=BOARD_LEFT; i