char white_holding[64], black_holding[64];
TimeMark lastNodeCountTime;
long lastNodeCount=0;
+int shiftKey; // [HGM] set by mouse handler
int have_sent_ICS_logon = 0;
int sending_ICS_login = 0;
long tc2;
char buf[MSG_SIZ], buf2[MSG_SIZ], *mytc = tc;
int min, sec=0;
- int len;
if(ti >= 0 && !strchr(tc, '+') && !strchr(tc, '/') ) mps = 0;
if(!strchr(tc, '+') && !strchr(tc, '/') && sscanf(tc, "%d:%d", &min, &sec) >= 1)
}
if (gameInfo.boardHeight != ranks || gameInfo.boardWidth != files ||
- weird && (int)gameInfo.variant <= (int)VariantShogi) {
+ weird && (int)gameInfo.variant < (int)VariantShogi) {
/* [HGM] We seem to have switched variant unexpectedly
* Try to guess new variant from board size
*/
strcat(parseList[moveNum - 1], " ");
strcat(parseList[moveNum - 1], elapsed_time);
/* currentMoveString is set as a side-effect of ParseOneMove */
- if(gameInfo.variant == VariantShogi && currentMoveString[4]) currentMoveString[4] = '+';
+ if(gameInfo.variant == VariantShogi && currentMoveString[4]) currentMoveString[4] = '^';
safeStrCpy(moveList[moveNum - 1], currentMoveString, sizeof(moveList[moveNum - 1])/sizeof(moveList[moveNum - 1][0]));
strcat(moveList[moveNum - 1], "\n");
break;
case WhiteNonPromotion:
case BlackNonPromotion:
- sprintf(user_move, "%c%c%c%c=\n", AAA + fromX, ONE + fromY, AAA + toX, ONE + toY);
+ sprintf(user_move, "%c%c%c%c==\n", AAA + fromX, ONE + fromY, AAA + toX, ONE + toY);
break;
case WhitePromotion:
case BlackPromotion:
int *fromX, *fromY, *toX, *toY;
char *promoChar;
{
- if (appData.debugMode) {
- fprintf(debugFP, "move to parse: %s\n", move);
- }
*moveType = yylexstr(moveNum, move, yy_textstr, sizeof yy_textstr);
switch (*moveType) {
*promoChoice = PieceToChar(BlackFerz); // no choice
return FALSE;
}
+ // no sense asking what we must promote to if it is going to explode...
+ if(gameInfo.variant == VariantAtomic && boards[currentMove][toY][toX] != EmptySquare) {
+ *promoChoice = PieceToChar(BlackQueen); // Queen as good as any
+ return FALSE;
+ }
if(autoQueen) { // predetermined
if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantLosers)
*promoChoice = PieceToChar(BlackKing); // in Suicide Q is the last thing we want
gameMode == IcsPlayingBlack && WhiteOnMove(currentMove);
if(appData.testLegality && !premove) {
moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
- fromY, fromX, toY, toX, NULLCHAR);
+ fromY, fromX, toY, toX, gameInfo.variant == VariantShogi ? '+' : NULLCHAR);
if(moveType != WhitePromotion && moveType != BlackPromotion)
return FALSE;
}
case IcsPlayingBlack:
if(WhiteOnMove(currentMove)) return FALSE;
break;
+ case EditGame:
+ break;
default:
return FALSE;
}
the previous line in Analysis Mode */
if ((gameMode == AnalyzeMode || gameMode == EditGame)
&& currentMove < forwardMostMove) {
- PushTail(currentMove, forwardMostMove); // [HGM] vari: save tail of game
+ if(appData.variations && shiftKey) PushTail(currentMove, forwardMostMove); // [HGM] vari: save tail of game
+ else forwardMostMove = currentMove;
}
/* If we need the chess program but it's dead, restart it */
DrawPosition(TRUE, NULL);
}
+int
+Explode(Board board, int fromX, int fromY, int toX, int toY)
+{
+ if(gameInfo.variant == VariantAtomic &&
+ (board[toY][toX] != EmptySquare || // capture?
+ toX != fromX && (board[fromY][fromX] == WhitePawn || // e.p. ?
+ board[fromY][fromX] == BlackPawn )
+ )) {
+ AnimateAtomicCapture(board, fromX, fromY, toX, toY);
+ return TRUE;
+ }
+ return FALSE;
+}
+
void LeftClick(ClickType clickType, int xPix, int yPix)
{
int x, y;
}
PromotionPopUp();
} else {
+ int oldMove = currentMove;
UserMoveEvent(fromX, fromY, toX, toY, promoChoice);
if (!appData.highlightLastMove || gotPremove) ClearHighlights();
if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
+ if(saveAnimate && !appData.animate && currentMove != oldMove && // drag-move was performed
+ Explode(boards[currentMove-1], fromX, fromY, toX, toY))
+ DrawPosition(TRUE, boards[currentMove]);
fromX = fromY = -1;
}
appData.animate = saveAnimate;
if(promoChar == '+') {
/* [HGM] Shogi-style promotions, to piece implied by original (Might overwrite orinary Pawn promotion) */
board[toY][toX] = (ChessSquare) (PROMOTED piece);
- } else if(!appData.testLegality) { // without legality testing, unconditionally believe promoChar
- board[toY][toX] = CharToPiece(promoChar);
+ } else if(!appData.testLegality && promoChar != NULLCHAR && promoChar != '=') { // without legality testing, unconditionally believe promoChar
+ board[toY][toX] = CharToPiece(piece < BlackPawn ? ToUpper(promoChar) : ToLower(promoChar));
}
if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)
&& promoChar != NULLCHAR && gameInfo.holdingsSize) {
} else {
commentList[index] = (char *) malloc(len + 6); // perhaps wastes 4...
if(addBraces)
- safeStrCpy(commentList[index], "{\n", sizeof(commentList[index])/sizeof(commentList[index][0]));
+ safeStrCpy(commentList[index], "{\n", 3);
else commentList[index][0] = NULLCHAR;
strcat(commentList[index], text);
strcat(commentList[index], "\n");
/* Note old gnuchess bug -- minutes:seconds used to not work.
Fixed in later versions, but still avoid :seconds
when seconds is 0. */
- snprintf(buf, MSG_SIZ, "level %d %ld %g\n", mps, tc/60000, inc/1000);
+ snprintf(buf, MSG_SIZ, "level %d %ld %g\n", mps, tc/60000, inc/1000.);
} else {
snprintf(buf, MSG_SIZ, "level %d %ld:%02d %g\n", mps, tc/60000,
- seconds, inc/1000);
+ seconds, inc/1000.);
}
}
SendToProgram(buf, cps);