X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=c487dd164339c5cef47b856db121a8ab52842a8a;hb=f856eb7ac5fbeec648f7fd27013905f0a5a26616;hp=a4f78524d57585c59b6af641ba345a26d530cf02;hpb=d82d80274f7fb7c07dcf12ba873bb4c842279171;p=xboard.git diff --git a/backend.c b/backend.c index a4f7852..c487dd1 100644 --- a/backend.c +++ b/backend.c @@ -5,7 +5,8 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free + * Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -4162,6 +4163,7 @@ read_from_ics (InputSourceRef isr, VOIDSTAR closure, char *data, int count, int fprintf(debugFP, "Sending premove:\n"); SendToICS(str); } else if (gotPremove) { + int oldFMM = forwardMostMove; gotPremove = 0; ClearPremoveHighlights(); if (appData.debugMode) @@ -4169,6 +4171,13 @@ read_from_ics (InputSourceRef isr, VOIDSTAR closure, char *data, int count, int UserMoveEvent(premoveFromX, premoveFromY, premoveToX, premoveToY, premovePromoChar); + if(forwardMostMove == oldFMM) { // premove was rejected, highlight last opponent move + if(moveList[oldFMM-1][1] != '@') + SetHighlights(moveList[oldFMM-1][0]-AAA, moveList[oldFMM-1][1]-ONE, + moveList[oldFMM-1][2]-AAA, moveList[oldFMM-1][3]-ONE); + else // (drop) + SetHighlights(-1, -1, moveList[oldFMM-1][2]-AAA, moveList[oldFMM-1][3]-ONE); + } } } @@ -5145,16 +5154,18 @@ SendMoveToProgram (int moveNum, ChessProgramState *cps) } else if(moveList[moveNum][4] == ';') { // [HGM] lion: move is double-step over intermediate square char *m = moveList[moveNum]; + static char c[2]; + *c = m[7]; // promoChar if((boards[moveNum][m[6]-ONE][m[5]-AAA] < BlackPawn) == (boards[moveNum][m[1]-ONE][m[0]-AAA] < BlackPawn)) // move is kludge to indicate castling snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d\n", m[0], m[1] - '0', // convert to two moves m[2], m[3] - '0', m[5], m[6] - '0', m[2] + (m[0] > m[5] ? 1 : -1), m[3] - '0'); else - snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d\n", m[0], m[1] - '0', // convert to two moves + snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d%s\n", m[0], m[1] - '0', // convert to two moves m[5], m[6] - '0', m[5], m[6] - '0', - m[2], m[3] - '0'); + m[2], m[3] - '0', c); SendToProgram(buf, cps); } else if(BOARD_HEIGHT > 10) { // [HGM] big: convert ranks to double-digit where needed @@ -5358,6 +5369,10 @@ CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char } else { sprintf(move, "%c%c%c%c%c\n", AAA + ff, ONE + rf, AAA + ft, ONE + rt, promoChar); + if(killX >= 0 && killY >= 0) { + sprintf(move+4, ";%c%c\n", AAA + killX, ONE + killY); + if(kill2X >= 0 && kill2Y >= 0) sprintf(move+7, "%c%c%c\n", AAA + killX, ONE + killY, promoChar); + } } } } @@ -5556,7 +5571,7 @@ ParseOneMove (char *move, int moveNum, ChessMove *moveType, int *fromX, int *fro *toX = currentMoveString[2] - AAA; *toY = currentMoveString[3] - ONE; *promoChar = currentMoveString[4]; - if(*promoChar == ';') *promoChar = NULLCHAR; + if(*promoChar == ';') *promoChar = currentMoveString[7]; if (*fromX < BOARD_LEFT || *fromX >= BOARD_RGHT || *fromY < 0 || *fromY >= BOARD_HEIGHT || *toX < BOARD_LEFT || *toX >= BOARD_RGHT || *toY < 0 || *toY >= BOARD_HEIGHT) { if (appData.debugMode) { @@ -6736,7 +6751,7 @@ HasPromotionChoice (int fromX, int fromY, int toX, int toY, char *promoChoice, i *promoChoice = PieceToChar(p++); if(*promoChoice != '.') break; } - return FALSE; + if(!*engineVariant) return FALSE; // if used as parent variant there might be promotion choice } // no sense asking what we must promote to if it is going to explode... if(gameInfo.variant == VariantAtomic && boards[currentMove][toY][toX] != EmptySquare) { @@ -6835,6 +6850,7 @@ OKToStartUserMove (int x, int y) case PlayFromGameFile: if(!shiftKey || !appData.variations) return FALSE; // [HGM] allow starting variation in this mode case EditGame: + case AnalyzeMode: if (!white_piece && WhiteOnMove(currentMove)) { DisplayMoveError(_("It is White's turn")); return FALSE; @@ -6953,7 +6969,7 @@ int doubleClick; Boolean addToBookFlag; void -UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) +UserMoveEvent (int fromX, int fromY, int toX, int toY, int promoChar) { ChessMove moveType; ChessSquare pup; @@ -7037,6 +7053,7 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) "fromY %d, toX %d, toY %d\n", fromX, fromY, toX, toY); } + DrawPosition(TRUE, boards[currentMove]); // [HGM] repair animation damage done by premove (in particular emptying from-square) return; } break; @@ -7058,6 +7075,7 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) "fromY %d, toX %d, toY %d\n", fromX, fromY, toX, toY); } + DrawPosition(TRUE, boards[currentMove]); return; } break; @@ -7141,7 +7159,8 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) if(addToBookFlag) { // adding moves to book char buf[MSG_SIZ], move[MSG_SIZ]; CoordsToAlgebraic(boards[currentMove], PosFlags(currentMove), fromY, fromX, toY, toX, promoChar, move); - if(killX >= 0) snprintf(move, MSG_SIZ, "%c%dx%c%d-%c%d", fromX + AAA, fromY + ONE - '0', killX + AAA, killY + ONE - '0', toX + AAA, toY + ONE - '0'); + if(killX >= 0) snprintf(move, MSG_SIZ, "%c%dx%c%d-%c%d%c", fromX + AAA, fromY + ONE - '0', + killX + AAA, killY + ONE - '0', toX + AAA, toY + ONE - '0', promoChar); snprintf(buf, MSG_SIZ, " 0.0%% 1 %s\n", move); AddBookMove(buf); addToBookFlag = FALSE; @@ -7442,8 +7461,8 @@ CanPromote (ChessSquare piece, int y) // some variants have fixed promotion piece, no promotion at all, or another selection mechanism if(IS_SHOGI(gameInfo.variant) || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat || - gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || - gameInfo.variant == VariantMakruk) return FALSE; + (gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || + gameInfo.variant == VariantMakruk) && !*engineVariant) return FALSE; return (piece == BlackPawn && y <= zone || piece == WhitePawn && y >= BOARD_HEIGHT-1-zone || piece == BlackLance && y <= zone || @@ -7974,6 +7993,23 @@ RightClick (ClickType action, int x, int y, int *fromX, int *fromY) } void +Wheel (int dir, int x, int y) +{ + if(gameMode == EditPosition) { + int xSqr = EventToSquare(x, BOARD_WIDTH); + int ySqr = EventToSquare(y, BOARD_HEIGHT); + if(ySqr < 0 || xSqr < BOARD_LEFT || xSqr >= BOARD_RGHT) return; + if(flipView) xSqr = BOARD_WIDTH - 1 - xSqr; else ySqr = BOARD_HEIGHT - 1 - ySqr; + do { + boards[currentMove][ySqr][xSqr] += dir; + if((int) boards[currentMove][ySqr][xSqr] < WhitePawn) boards[currentMove][ySqr][xSqr] = BlackKing; + if((int) boards[currentMove][ySqr][xSqr] > BlackKing) boards[currentMove][ySqr][xSqr] = WhitePawn; + } while(PieceToChar(boards[currentMove][ySqr][xSqr]) == '.'); + DrawPosition(FALSE, boards[currentMove]); + } else if(dir > 0) ForwardEvent(); else BackwardEvent(); +} + +void SendProgramStatsToFrontend (ChessProgramState * cps, ChessProgramStats * cpstats) { // char * hint = lastHint; @@ -9732,6 +9768,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h [AS] Protect the thinkOutput buffer from overflow... this is only useful if buf1 hasn't overflowed first! */ + if((gameMode == AnalyzeMode && appData.whitePOV || appData.scoreWhite) && !WhiteOnMove(forwardMostMove)) curscore *= -1; if(curscore >= MATE_SCORE) snprintf(score_buf, MSG_SIZ, "#%d", curscore - MATE_SCORE); else if(curscore <= -MATE_SCORE) @@ -10459,10 +10496,10 @@ MakeMove (int fromX, int fromY, int toX, int toY, int promoChar) if(killX >= 0 && killY >= 0) x = killX, y = killY; // [HGM] lion: make SAN move to intermediate square, if there is one (void) CoordsToAlgebraic(boards[forwardMostMove], PosFlags(forwardMostMove), - fromY, fromX, y, x, promoChar, + fromY, fromX, y, x, (killX < 0)*promoChar, s); if(killX >= 0 && killY >= 0) - sprintf(s + strlen(s), "%c%c%d", p == EmptySquare || toX == fromX && toY == fromY ? '-' : 'x', toX + AAA, toY + ONE - '0'); + sprintf(s + strlen(s), "%c%c%d%c", p == EmptySquare || toX == fromX && toY == fromY ? '-' : 'x', toX + AAA, toY + ONE - '0', promoChar); if(serverMoves != NULL) { /* [HGM] write moves on file for broadcasting (should be separate routine, really) */ int timeLeft; static int lastLoadFlag=0; int king, piece; @@ -12129,7 +12166,7 @@ LoadGameOneMove (ChessMove readAhead) toX = currentMoveString[2] - AAA; toY = currentMoveString[3] - ONE; promoChar = currentMoveString[4]; - if(promoChar == ';') promoChar = NULLCHAR; + if(promoChar == ';') promoChar = currentMoveString[7]; break; case WhiteDrop: