X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=fac9abdc871ff1251cc353f5d84c1e76c350faf4;hb=da8802ac4d06115296e0f8ba955ecf5570741d08;hp=0e0f80eec18f95d78e9a46defdb1b336a71bd612;hpb=2cbef99e7202b7af01c5fef277501fc5baa7b50a;p=xboard.git diff --git a/backend.c b/backend.c index 0e0f80e..fac9abd 100644 --- a/backend.c +++ b/backend.c @@ -566,6 +566,13 @@ ChessSquare aseanArray[2][BOARD_FILES] = { /* [HGM] (movGen knows about Shatranj BlackKing, BlackMan, BlackKnight, BlackRook } }; +ChessSquare lionArray[2][BOARD_FILES] = { + { WhiteRook, WhiteLion, WhiteBishop, WhiteQueen, + WhiteKing, WhiteBishop, WhiteKnight, WhiteRook }, + { BlackRook, BlackLion, BlackBishop, BlackQueen, + BlackKing, BlackBishop, BlackKnight, BlackRook } +}; + #if (BOARD_FILES>=10) ChessSquare ShogiArray[2][BOARD_FILES] = { @@ -1195,6 +1202,7 @@ InitBackEnd1 () case VariantSChess: /* S-Chess, should work */ case VariantGrand: /* should work */ case VariantSpartan: /* should work */ + case VariantLion: /* should work */ break; } } @@ -5235,7 +5243,7 @@ UploadGameEvent () SendToICS(ics_type == ICS_ICC ? "tag result Game in progress\n" : "commit\n"); } -static int killX = -1, killY = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove +int killX = -1, killY = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove void CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char move[7]) @@ -5289,8 +5297,8 @@ Sweep (int step) else if(promoSweep == WhiteKing && step > 0) promoSweep = BlackKing; if(!step) step = -1; } while(PieceToChar(promoSweep) == '.' || PieceToChar(promoSweep) == '~' || promoSweep == pawn || - appData.testLegality && (promoSweep == king || - IS_SHOGI(gameInfo.variant) && promoSweep != CHUPROMOTED last && last != CHUPROMOTED promoSweep && last != promoSweep)); + appData.testLegality && (promoSweep == king || promoSweep == WhiteLion || promoSweep == BlackLion) || + IS_SHOGI(gameInfo.variant) && promoSweep != CHUPROMOTED last && last != CHUPROMOTED promoSweep && last != promoSweep); if(toX >= 0) { int victim = boards[currentMove][toY][toX]; boards[currentMove][toY][toX] = promoSweep; @@ -5394,6 +5402,7 @@ ParseOneMove (char *move, int moveNum, ChessMove *moveType, int *fromX, int *fro case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteCapturesEnPassant: case BlackCapturesEnPassant: case WhiteKingSideCastle: @@ -6031,6 +6040,10 @@ InitPosition (int redraw) pieces = SpartanArray; SetCharTable(pieceToChar, "PNBRQ................K......lwg.....c...h..k"); break; + case VariantLion: + pieces = lionArray; + SetCharTable(pieceToChar, "PNBRQ................LKpnbrq................lk"); + break; case VariantFairy: pieces = fairyArray; SetCharTable(pieceToChar, "PNBRQFEACWMOHIJGDVLSUKpnbrqfeacwmohijgdvlsuk"); @@ -6422,7 +6435,7 @@ HasPromotionChoice (int fromX, int fromY, int toX, int toY, char *promoChoice, i if(gameInfo.variant == VariantChu) { int p = piece >= BlackPawn ? BLACK_TO_WHITE piece : piece; promotionZoneSize = BOARD_HEIGHT/3; - highestPromotingPiece = (p >= WhiteLion || PieceToChar(piece + 22) == '.') ? WhitePawn : WhiteKing; + highestPromotingPiece = (p >= WhiteLion || PieceToChar(piece + 22) == '.') ? WhitePawn : WhiteLion; } else if(gameInfo.variant == VariantShogi) { promotionZoneSize = BOARD_HEIGHT/3; highestPromotingPiece = (int)WhiteAlfil; @@ -7106,10 +7119,10 @@ Mark (Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VO { typedef char Markers[BOARD_RANKS][BOARD_FILES]; Markers *m = (Markers *) closure; - if(rf == fromY && ff == fromX) + if(rf == fromY && ff == fromX && (killX < 0 && !(rt == rf && ft == ff) || abs(ft-killX) < 2 && abs(rt-killY) < 2)) (*m)[rt][ft] = 1 + (board[rt][ft] != EmptySquare || kind == WhiteCapturesEnPassant - || kind == BlackCapturesEnPassant); + || kind == BlackCapturesEnPassant) + 3*(kind == FirstLeg && killX < 0); else if(flags & F_MANDATORY_CAPTURE && board[rt][ft] != EmptySquare) (*m)[rt][ft] = 3; } @@ -7297,7 +7310,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) if(gameMode == AnalyzeMode && (pausing || controlKey) && first.excludeMoves) { // use pause state to exclude moves doubleClick = TRUE; gatingPiece = boards[currentMove][y][x]; } - fromX = x; fromY = y; toX = toY = -1; + fromX = x; fromY = y; toX = toY = killX = killY = -1; if(!appData.oneClick || !OnlyMove(&x, &y, FALSE) || // even if only move, we treat as normal when this would trigger a promotion popup, to allow sweep selection appData.sweepSelect && CanPromote(boards[currentMove][fromY][fromX], fromY) && originalY != y) { @@ -7325,7 +7338,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) } /* fromX != -1 */ - if (clickType == Press && gameMode != EditPosition && killX < 0) { + if (clickType == Press && gameMode != EditPosition) { ChessSquare fromP; ChessSquare toP; int frc; @@ -7337,16 +7350,18 @@ LeftClick (ClickType clickType, int xPix, int yPix) fromP = boards[currentMove][fromY][fromX]; toP = boards[currentMove][y][x]; frc = gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom || gameInfo.variant == VariantSChess; - if ((WhitePawn <= fromP && fromP <= WhiteKing && + if( (killX < 0 || x != fromX || y != fromY) && // [HGM] lion: do not interpret igui as deselect! + ((WhitePawn <= fromP && fromP <= WhiteKing && WhitePawn <= toP && toP <= WhiteKing && !(fromP == WhiteKing && toP == WhiteRook && frc) && !(fromP == WhiteRook && toP == WhiteKing && frc)) || (BlackPawn <= fromP && fromP <= BlackKing && BlackPawn <= toP && toP <= BlackKing && !(fromP == BlackRook && toP == BlackKing && frc) && // allow also RxK as FRC castling - !(fromP == BlackKing && toP == BlackRook && frc))) { + !(fromP == BlackKing && toP == BlackRook && frc)))) { /* Clicked again on same color piece -- changed his mind */ second = (x == fromX && y == fromY); + killX = killY = -1; if(second && gameMode == AnalyzeMode && SubtractTimeMarks(&lastClickTime, &prevClickTime) < 200) { second = FALSE; // first double-click rather than scond click doubleClick = first.excludeMoves; // used by UserMoveEvent to recognize exclude moves @@ -7417,7 +7432,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) clearFlag = 0; - if(gameMode != EditPosition && !appData.testLegality && !legal[y][x] && (x != killX || y != killY)) { + if(gameMode != EditPosition && !appData.testLegality && !legal[y][x] && (x != killX || y != killY) && !sweepSelecting) { if(dragging) DragPieceEnd(xPix, yPix), dragging = 0; DisplayMessage(_("only marked squares are legal"),""); DrawPosition(TRUE, NULL); @@ -7429,7 +7444,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) if(!sweepSelecting) { toX = x; toY = y; - } else sweepSelecting = 0; // this must be the up-click corresponding to the down-click that started the sweep + } saveAnimate = appData.animate; if (clickType == Press) { @@ -7466,6 +7481,13 @@ LeftClick (ClickType clickType, int xPix, int yPix) } else { ClearHighlights(); } + } else if(sweepSelecting) { // this must be the up-click corresponding to the down-click that started the sweep + sweepSelecting = 0; + if (appData.animate || appData.highlightLastMove) { + SetHighlights(fromX, fromY, toX, toY); + } else { + ClearHighlights(); + } } else { #if 0 // [HGM] this must be done after the move is made, as with arrow it could lead to a board redraw with piece still on from square @@ -7476,11 +7498,12 @@ LeftClick (ClickType clickType, int xPix, int yPix) ClearHighlights(); } #endif - if(!dragging || marker[y][x] == 5) { // [HGM] lion: this was the release of a to-click or drag on a cyan square + if(marker[y][x] == 5) { // [HGM] lion: this was the release of a to-click or drag on a cyan square dragging *= 2; // flag button-less dragging if we are dragging MarkTargetSquares(1); if(x == killX && y == killY) killX = killY = -1; else { killX = x; killY = y; //remeber this square as intermediate + MarkTargetSquares(0); ReportClick("put", x, y); // and inform engine ReportClick("lift", x, y); return; @@ -8265,7 +8288,7 @@ HandleMachineMove (char *message, ChessProgramState *cps) char realname[MSG_SIZ]; int fromX, fromY, toX, toY; ChessMove moveType; - char promoChar; + char promoChar, roar; char *p, *pv=buf1; int machineWhite, oldError; char *bookHit; @@ -8581,10 +8604,12 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. cps->other->maybeThinking = TRUE; } + roar = (killX >= 0 && IS_LION(boards[forwardMostMove][toY][toX])); + ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ if (!pausing && appData.ringBellAfterMoves) { - RingBell(); + if(!roar) RingBell(); } /* @@ -9475,6 +9500,7 @@ ParseGameHistory (char *game) case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteCapturesEnPassant: case BlackCapturesEnPassant: case WhiteKingSideCastle: @@ -9632,14 +9658,22 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } piece = board[toY][toX] = (ChessSquare) fromX; } else { + ChessSquare victim; int i; if( killX >= 0 && killY >= 0 ) // [HGM] lion: Lion trampled over something + victim = board[killY][killX], board[killY][killX] = EmptySquare, board[EP_STATUS] = EP_CAPTURE; - if( board[toY][toX] != EmptySquare ) + if( board[toY][toX] != EmptySquare ) { board[EP_STATUS] = EP_CAPTURE; + if( (fromX != toX || fromY != toY) && // not igui! + (captured == WhiteLion && board[fromY][fromX] != BlackLion || + captured == BlackLion && board[fromY][fromX] != WhiteLion ) ) { // [HGM] lion: Chu Lion-capture rules + board[EP_STATUS] = EP_IRON_LION; // non-Lion x Lion: no counter-strike allowed + } + } if( board[fromY][fromX] == WhiteLance || board[fromY][fromX] == BlackLance ) { if( gameInfo.variant != VariantSuper && gameInfo.variant != VariantShogi ) @@ -9925,7 +9959,6 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) board[BOARD_HEIGHT-1-k][0] = EmptySquare; } } - } /* Updates forwardMostMove */ @@ -10038,8 +10071,6 @@ MakeMove (int fromX, int fromY, int toX, int toY, int promoChar) strcat(parseList[forwardMostMove - 1], "#"); break; } - - killX = killY = -1; // [HGM] lion: used up } /* Updates currentMove if not pausing */ @@ -10059,6 +10090,8 @@ ShowMove (int fromX, int fromY, int toX, int toY) currentMove = forwardMostMove; } + killX = killY = -1; // [HGM] lion: used up + if (instant) return; DisplayMove(currentMove - 1); @@ -10868,7 +10901,7 @@ GameEnds (ChessMove result, char *resultDetails, int whosays) result, resultDetails ? resultDetails : "(null)", whosays); } - fromX = fromY = -1; // [HGM] abort any move the user is entering. + fromX = fromY = killX = killY = -1; // [HGM] abort any move the user is entering. // [HGM] lion if(pausing) PauseEvent(); // can happen when we abort a paused game (New Game or Quit) @@ -11364,6 +11397,7 @@ Reset (int redraw, int init) ClearPremoveHighlights(); gotPremove = FALSE; alarmSounded = FALSE; + killX = killY = -1; // [HGM] lion GameEnds(EndOfFile, NULL, GE_PLAYER); if(appData.serverMovesName != NULL) { @@ -11544,6 +11578,7 @@ LoadGameOneMove (ChessMove readAhead) case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteKingSideCastle: case WhiteQueenSideCastle: case BlackKingSideCastle: @@ -11565,6 +11600,7 @@ LoadGameOneMove (ChessMove readAhead) toX = currentMoveString[2] - AAA; toY = currentMoveString[3] - ONE; promoChar = currentMoveString[4]; + if(promoChar == ';') promoChar = NULLCHAR; break; case WhiteDrop: @@ -11731,6 +11767,7 @@ LoadGameOneMove (ChessMove readAhead) thinkOutput[0] = NULLCHAR; MakeMove(fromX, fromY, toX, toY, promoChar); + killX = killY = -1; // [HGM] lion: used up currentMove = forwardMostMove; return TRUE; } @@ -12228,6 +12265,7 @@ GameContainsPosition (FILE *f, ListGame *lg) case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteKingSideCastle: case WhiteQueenSideCastle: case BlackKingSideCastle: @@ -12292,6 +12330,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) if (gameMode != BeginningOfGame) { Reset(FALSE, TRUE); } + killX = killY = -1; // [HGM] lion: in case we did not Reset gameFileFP = f; if (lastLoadGameFP != NULL && lastLoadGameFP != f) { @@ -12445,6 +12484,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) break; case NormalMove: + case FirstLeg: /* Only a NormalMove can be at the start of a game * without a position diagram. */ if (lastLoadGameStart == EndOfFile ) {