X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=6675344b945a1c61985e18cda44bf6bfb306a794;hb=729cea0f6cc7830c65b801eb7172ef68d57c2ff7;hp=f449d2610c8620914ddc25f682f2d9cb80145a7a;hpb=deb3473452a674b82d27b03fcf7e570c1cb03841;p=xboard.git diff --git a/backend.c b/backend.c index f449d26..6675344 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; } } @@ -5008,6 +5016,11 @@ SendMoveToProgram (int moveNum, ChessProgramState *cps) char buf[MSG_SIZ]; if(moveList[moveNum][1] == '@' && moveList[moveNum][0] == '@') { + if(gameInfo.variant == VariantLion || gameInfo.variant == VariantChu) { + sprintf(buf, "%s@@@@\n", cps->useUsermove ? "usermove " : ""); + SendToProgram(buf, cps); + return; + } // null move in variant where engine does not understand it (for analysis purposes) SendBoard(cps, moveNum + 1); // send position after move in stead. return; @@ -5050,16 +5063,18 @@ SendMoveToProgram (int moveNum, ChessProgramState *cps) } else SendToProgram(moveList[moveNum], cps); } else + if(moveList[moveNum][4] == ';') { // [HGM] lion: move is double-step over intermediate square + snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d\n", moveList[moveNum][0], moveList[moveNum][1] - '0', // convert to two moves + moveList[moveNum][5], moveList[moveNum][6] - '0', + moveList[moveNum][5], moveList[moveNum][6] - '0', + moveList[moveNum][2], moveList[moveNum][3] - '0'); + SendToProgram(buf, cps); + } else if(BOARD_HEIGHT > 10) { // [HGM] big: convert ranks to double-digit where needed if(moveList[moveNum][1] == '@' && (BOARD_HEIGHT < 16 || moveList[moveNum][0] <= 'Z')) { // drop move if(moveList[moveNum][0]== '@') snprintf(buf, MSG_SIZ, "@@@@\n"); else snprintf(buf, MSG_SIZ, "%c@%c%d%s", moveList[moveNum][0], moveList[moveNum][2], moveList[moveNum][3] - '0', moveList[moveNum]+4); - } else if(moveList[moveNum][4] == ';') { // [HGM] lion: move is double-step over intermediate square - snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d\n", moveList[moveNum][0], moveList[moveNum][1] - '0', // convert to two moves - moveList[moveNum][5], moveList[moveNum][6] - '0', - moveList[moveNum][5], moveList[moveNum][6] - '0', - moveList[moveNum][2], moveList[moveNum][3] - '0'); } else snprintf(buf, MSG_SIZ, "%c%d%c%d%s", moveList[moveNum][0], moveList[moveNum][1] - '0', moveList[moveNum][2], moveList[moveNum][3] - '0', moveList[moveNum]+4); @@ -5235,7 +5250,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 +5304,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 +5409,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: @@ -5427,7 +5443,8 @@ ParseOneMove (char *move, int moveNum, ChessMove *moveType, int *fromX, int *fro if (appData.testLegality) { return (*moveType != IllegalMove); } else { - return !(*fromX == *toX && *fromY == *toY) && boards[moveNum][*fromY][*fromX] != EmptySquare && + return !(*fromX == *toX && *fromY == *toY && killX < 0) && boards[moveNum][*fromY][*fromX] != EmptySquare && + // [HGM] lion: if this is a double move we are less critical WhiteOnMove(moveNum) == (boards[moveNum][*fromY][*fromX] < BlackPawn); } @@ -6031,6 +6048,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 +6443,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; @@ -7101,15 +7122,17 @@ MarkByFEN(char *fen) DrawPosition(TRUE, NULL); } +static char baseMarker[BOARD_RANKS][BOARD_FILES], baseLegal[BOARD_RANKS][BOARD_FILES]; + void Mark (Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VOIDSTAR closure) { 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; } @@ -7118,7 +7141,7 @@ MarkTargetSquares (int clear) { int x, y, sum=0; if(clear) { // no reason to ever suppress clearing - for(x=0; xwhich)); DisplayMoveError(buf1); - snprintf(buf1, MSG_SIZ*10, "Xboard: Forfeit due to invalid move: %s (%c%c%c%c) res=%d", - machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, moveType); + snprintf(buf1, MSG_SIZ*10, "Xboard: Forfeit due to invalid move: %s (%c%c%c%c via %c%c) res=%d", + machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, killX+AAA, killY+ONE, moveType); if (gameMode == TwoMachinesPlay) { GameEnds(machineWhite ? BlackWins : WhiteWins, buf1, GE_XBOARD); @@ -8576,10 +8613,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(); } /* @@ -9470,6 +9509,7 @@ ParseGameHistory (char *game) case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteCapturesEnPassant: case BlackCapturesEnPassant: case WhiteKingSideCastle: @@ -9627,14 +9667,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 ) @@ -9920,7 +9968,6 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) board[BOARD_HEIGHT-1-k][0] = EmptySquare; } } - } /* Updates forwardMostMove */ @@ -10033,8 +10080,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 */ @@ -10054,6 +10099,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); @@ -10863,7 +10910,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) @@ -11359,6 +11406,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) { @@ -11539,6 +11587,7 @@ LoadGameOneMove (ChessMove readAhead) case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteKingSideCastle: case WhiteQueenSideCastle: case BlackKingSideCastle: @@ -11560,6 +11609,7 @@ LoadGameOneMove (ChessMove readAhead) toX = currentMoveString[2] - AAA; toY = currentMoveString[3] - ONE; promoChar = currentMoveString[4]; + if(promoChar == ';') promoChar = NULLCHAR; break; case WhiteDrop: @@ -11726,6 +11776,7 @@ LoadGameOneMove (ChessMove readAhead) thinkOutput[0] = NULLCHAR; MakeMove(fromX, fromY, toX, toY, promoChar); + killX = killY = -1; // [HGM] lion: used up currentMove = forwardMostMove; return TRUE; } @@ -12223,6 +12274,7 @@ GameContainsPosition (FILE *f, ListGame *lg) case WhiteNonPromotion: case BlackNonPromotion: case NormalMove: + case FirstLeg: case WhiteKingSideCastle: case WhiteQueenSideCastle: case BlackKingSideCastle: @@ -12287,6 +12339,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) { @@ -12440,6 +12493,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 ) {