* 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
*
fprintf(debugFP, "Sending premove:\n");
SendToICS(str);
} else if (gotPremove) {
+ int oldFMM = forwardMostMove;
gotPremove = 0;
ClearPremoveHighlights();
if (appData.debugMode)
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);
+ }
}
}
} 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
} 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);
+ }
}
}
}
*toX = currentMoveString[2] - AAA;
*toY = currentMoveString[3] - ONE;
*promoChar = currentMoveString[4];
+ 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) {
*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) {
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;
"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;
"fromY %d, toX %d, toY %d\n",
fromX, fromY, toX, toY);
}
+ DrawPosition(TRUE, boards[currentMove]);
return;
}
break;
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;
// 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 ||
}
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;
[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)
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;
toX = currentMoveString[2] - AAA;
toY = currentMoveString[3] - ONE;
promoChar = currentMoveString[4];
- if(promoChar == ';') promoChar = NULLCHAR;
+ if(promoChar == ';') promoChar = currentMoveString[7];
break;
case WhiteDrop: