X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=b269cde60498a8876f4daba0d831bf7ddf9e1b30;hb=e22090f94af45d13d5e735e3227ff4573e62654e;hp=31d74e273cd07b17f3615affb402359c8f81903c;hpb=4385cc4c1ac6cf82a28b2990d62f934f4f3038b1;p=xboard.git diff --git a/backend.c b/backend.c index 31d74e2..b269cde 100644 --- a/backend.c +++ b/backend.c @@ -131,9 +131,16 @@ extern int gettimeofday(struct timeval *, struct timezone *); #ifdef ENABLE_NLS # define _(s) gettext (s) # define N_(s) gettext_noop (s) +# define T_(s) gettext(s) #else -# define _(s) (s) -# define N_(s) s +# ifdef WIN32 +# define _(s) T_(s) +# define N_(s) s +# else +# define _(s) (s) +# define N_(s) s +# define T_(s) s +# endif #endif @@ -714,8 +721,8 @@ InitBackEnd1() /* [AS] Adjudication threshold */ adjudicateLossThreshold = appData.adjudicateLossThreshold; - first.which = "first"; - second.which = "second"; + first.which = _("first"); + second.which = _("second"); first.maybeThinking = second.maybeThinking = FALSE; first.pr = second.pr = NoProc; first.isr = second.isr = NULL; @@ -4568,6 +4575,10 @@ SendMoveToICS(moveType, fromX, fromY, toX, toY) /* POP Fabien */ sprintf(user_move, "o-o-o\n"); break; + case WhiteNonPromotion: + case BlackNonPromotion: + sprintf(user_move, "%c%c%c%c=\n", AAA + fromX, ONE + fromY, AAA + toX, ONE + toY); + break; case WhitePromotionQueen: case BlackPromotionQueen: case WhitePromotionRook: @@ -4796,6 +4807,8 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) case BlackPromotionKnight: case WhitePromotionKing: case BlackPromotionKing: + case WhiteNonPromotion: + case BlackNonPromotion: case NormalMove: case WhiteCapturesEnPassant: case BlackCapturesEnPassant: @@ -6595,8 +6608,9 @@ Count(Board board, int pCnt[], int *nW, int *nB, int *wStale, int *bStale, int * for(p=WhitePawn; p<=EmptySquare; p++) pCnt[p] = 0; for(r=0; r 2) return FALSE; // no trivial draws with more than 1 major + if(myPawns == 2 && nMine == 3) // KPP + return majorDefense || pCnt[BlackFerz-side] + pCnt[BlackAlfil-side] >= 3; + if(myPawns == 1 && nMine == 2) // KP + return majorDefense || pCnt[BlackFerz-side] + pCnt[BlackAlfil-side] + pCnt[BlackPawn-side] >= 1; + if(myPawns == 1 && nMine == 3 && pCnt[WhiteKnight+side]) // KHP + return majorDefense || pCnt[BlackFerz-side] + pCnt[BlackAlfil-side]*2 >= 5; + if(myPawns) return FALSE; + if(pCnt[WhiteRook+side]) + return pCnt[BlackRook-side] || + pCnt[BlackCannon-side] && (pCnt[BlackFerz-side] >= 2 || pCnt[BlackAlfil-side] >= 2) || + pCnt[BlackKnight-side] && pCnt[BlackFerz-side] + pCnt[BlackAlfil-side] > 2 || + pCnt[BlackFerz-side] + pCnt[BlackAlfil-side] >= 4; + if(pCnt[WhiteCannon+side]) { + if(pCnt[WhiteFerz+side] + myPawns == 0) return TRUE; // Cannon needs platform + return majorDefense || pCnt[BlackAlfil-side] >= 2; + } + if(pCnt[WhiteKnight+side]) + return majorDefense || pCnt[BlackFerz-side] >= 2 || pCnt[BlackAlfil-side] + pCnt[BlackPawn-side] >= 1; + return FALSE; +} + +int MatingPotential(int pCnt[], int side, int nMine, int nHis, int stale, int bisColor) { VariantClass v = gameInfo.variant; @@ -6798,12 +6841,14 @@ Adjudicate(ChessProgramState *cps) } /* Then some trivial draws (only adjudicate, cannot be claimed) */ - if(nrW + nrB == 4 && + if(gameInfo.variant == VariantXiangqi ? + SufficientDefence(nr, WhitePawn, nrW, nrB) && SufficientDefence(nr, BlackPawn, nrB, nrW) + : nrW + nrB == 4 && ( nr[WhiteRook] == 1 && nr[BlackRook] == 1 /* KRKR */ || nr[WhiteQueen] && nr[BlackQueen]==1 /* KQKQ */ || nr[WhiteKnight]==2 || nr[BlackKnight]==2 /* KNNK */ || nr[WhiteKnight]+nr[WhiteBishop] == 1 && nr[BlackKnight]+nr[BlackBishop] == 1 /* KBKN, KBKB, KNKN */ - ) ) { + ) ) { if(--moveCount < 0 && appData.trivialDraws && canAdjudicate) { /* if the first 3 moves do not show a tactical win, declare draw */ if(engineOpponent) { @@ -8131,6 +8176,8 @@ ParseGameHistory(game) case BlackPromotionKnight: case WhitePromotionKing: case BlackPromotionKing: + case WhiteNonPromotion: + case BlackNonPromotion: case NormalMove: case WhiteCapturesEnPassant: case BlackCapturesEnPassant: @@ -8277,7 +8324,6 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board) /* [HGM] compute & store e.p. status and castling rights for new position */ /* we can always do that 'in place', now pointers to these rights are passed to ApplyMove */ - { int i; if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A; oldEP = (signed char)board[EP_STATUS]; @@ -8286,6 +8332,16 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board) if( board[toY][toX] != EmptySquare ) board[EP_STATUS] = EP_CAPTURE; + /* [HGM] In Shatranj and Courier all promotions are to Ferz */ + if((gameInfo.variant==VariantShatranj || gameInfo.variant==VariantCourier || gameInfo.variant == VariantMakruk) + && promoChar != 0) promoChar = PieceToChar(WhiteFerz); + + if (fromY == DROP_RANK) { + /* must be first */ + piece = board[toY][toX] = (ChessSquare) fromX; + } else { + int i; + if( board[fromY][fromX] == WhitePawn ) { if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers board[EP_STATUS] = EP_PAWN_MOVE; @@ -8317,18 +8373,8 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board) ) board[CASTLING][i] = NoRights; // revoke for moved or captured piece } - } - - /* [HGM] In Shatranj and Courier all promotions are to Ferz */ - if((gameInfo.variant==VariantShatranj || gameInfo.variant==VariantCourier || gameInfo.variant == VariantMakruk) - && promoChar != 0) promoChar = PieceToChar(WhiteFerz); - - if (fromX == toX && fromY == toY) return; + if (fromX == toX && fromY == toY) return; - if (fromY == DROP_RANK) { - /* must be first */ - piece = board[toY][toX] = (ChessSquare) fromX; - } else { piece = board[fromY][fromX]; /* [HGM] remember, for Shogi promotion */ king = piece < (int) BlackPawn ? WhiteKing : BlackKing; /* [HGM] Knightmate simplify testing for castling */ if(gameInfo.variant == VariantKnightmate) @@ -9334,7 +9380,12 @@ GameEnds(result, resultDetails, whosays) gameMode = nextGameMode; ModeHighlight(); endingGame = 0; /* [HGM] crash */ - if(popupRequested) DisplayFatalError(buf, 0, 0); // [HGM] crash: this call GameEnds recursively through ExitEvent! Make it a harmless tail recursion. + if(popupRequested) { // [HGM] crash: this calls GameEnds recursively through ExitEvent! Make it a harmless tail recursion. + if(matchMode == TRUE) DisplayFatalError(buf, 0, 0); else { + matchMode = FALSE; appData.matchGames = matchGame = 0; + DisplayNote(buf); + } + } } /* Assumes program was just initialized (initString sent). @@ -9602,6 +9653,8 @@ LoadGameOneMove(readAhead) case BlackPromotionKnight: case WhitePromotionKing: case BlackPromotionKing: + case WhiteNonPromotion: + case BlackNonPromotion: case NormalMove: case WhiteKingSideCastle: case WhiteQueenSideCastle: @@ -13970,7 +14023,7 @@ DisplayMove(moveNumber) sprintf(res, " %s", PGNResult(gameInfo.result)); } else { sprintf(res, " {%s} %s", - gameInfo.resultDetails, PGNResult(gameInfo.result)); + T_(gameInfo.resultDetails), PGNResult(gameInfo.result)); } } else { res[0] = NULLCHAR;