int have_sent_ICS_logon = 0;
int movesPerSession;
int suddenDeath, whiteStartMove, blackStartMove; /* [HGM] for implementation of 'any per time' sessions, as in first part of byoyomi TC */
-long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement, lastWhite, lastBlack;
+long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement, lastWhite, lastBlack, activePartnerTime;
Boolean adjustedClock;
long timeControl_2; /* [AS] Allow separate time controls */
-char *fullTimeControlString = NULL, *nextSession, *whiteTC, *blackTC; /* [HGM] secondary TC: merge of MPS, TC and inc */
+char *fullTimeControlString = NULL, *nextSession, *whiteTC, *blackTC, activePartner; /* [HGM] secondary TC: merge of MPS, TC and inc */
long timeRemaining[2][MAX_MOVES];
int matchGame = 0, nextGame = 0, roundNr = 0;
Boolean waitingForGame = FALSE;
board[i][j+newHoldingsWidth-gameInfo.holdingsWidth] =
board[i][j];
}
+ board[HOLDINGS_SET] = 0;
gameInfo.boardWidth = newWidth;
gameInfo.boardHeight = newHeight;
gameInfo.holdingsWidth = newHoldingsWidth;
if((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack)
&& newGameMode == IcsObserving && gamenum != ics_gamenum && appData.bgObserve) {
// [HGM] bughouse: don't act on alien boards while we play. Just parse the board and save it */
+ int fac = strchr(elapsed_time, '.') ? 1 : 1000;
char *toSqr;
for (k = 0; k < ranks; k++) {
for (j = 0; j < files; j++)
if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual
if(partnerUp) DrawPosition(FALSE, partnerBoard);
if(twoBoards) {
- DisplayWhiteClock(white_time, to_play == 'W');
- DisplayBlackClock(black_time, to_play != 'W');
+ DisplayWhiteClock(white_time*fac, to_play == 'W');
+ DisplayBlackClock(black_time*fac, to_play != 'W');
+ activePartner = to_play;
+ activePartnerTime = to_play == 'W' ? white_time*fac : black_time*fac;
partnerUp = 0; flipView = !flipView; } // [HGM] dual
- snprintf(partnerStatus, MSG_SIZ,"W: %d:%02d B: %d:%02d (%d-%d) %c", white_time/60000, (white_time%60000)/1000,
- (black_time/60000), (black_time%60000)/1000, white_stren, black_stren, to_play);
+ snprintf(partnerStatus, MSG_SIZ,"W: %d:%02d B: %d:%02d (%d-%d) %c", white_time*fac/60000, (white_time*fac%60000)/1000,
+ (black_time*fac/60000), (black_time*fac%60000)/1000, white_stren, black_stren, to_play);
DisplayMessage(partnerStatus, "");
partnerBoardValid = TRUE;
return;
}
if (gameInfo.boardHeight != ranks || gameInfo.boardWidth != files ||
+ move_str[1] == '@' && !gameInfo.holdingsWidth ||
weird && (int)gameInfo.variant < (int)VariantShogi) {
/* [HGM] We seem to have switched variant unexpectedly
* Try to guess new variant from board size
if(ranks == 10 && files == 9) newVariant = VariantXiangqi; else
if(ranks == 8 && files == 12) newVariant = VariantCourier; else
if(ranks == 9 && files == 9) newVariant = VariantShogi; else
- if(!weird) newVariant = VariantNormal;
+ if(ranks == 10 && files == 10) newVariant = VariantGrand; else
+ if(!weird) newVariant = move_str[1] == '@' ? VariantCrazyhouse : VariantNormal;
VariantSwitch(boards[currentMove], newVariant); /* temp guess */
/* Get a move list just to see the header, which
will tell us whether this is really bug or zh */
} while(PieceToChar(promoSweep) == '.' || PieceToChar(promoSweep) == '~' || promoSweep == pawn ||
appData.testLegality && (promoSweep == king ||
gameInfo.variant == VariantShogi && promoSweep != PROMOTED last && last != PROMOTED promoSweep && last != promoSweep));
+ if(toX >= 0) {
+ int victim = boards[currentMove][toY][toX];
+ boards[currentMove][toY][toX] = promoSweep;
+ DrawPosition(FALSE, boards[currentMove]);
+ boards[currentMove][toY][toX] = victim;
+ } else
ChangeDragPiece(promoSweep);
}
MarkTargetSquares (int clear)
{
int x, y;
+ if(clear) // no reason to ever suppress clearing
+ for(x=0; x<BOARD_WIDTH; x++) for(y=0; y<BOARD_HEIGHT; y++) marker[y][x] = 0;
if(!appData.markers || !appData.highlightDragging || appData.icsActive && gameInfo.variant < VariantShogi ||
!appData.testLegality || gameMode == EditPosition) return;
- if(clear) {
- for(x=0; x<BOARD_WIDTH; x++) for(y=0; y<BOARD_HEIGHT; y++) marker[y][x] = 0;
- } else {
+ if(!clear) {
int capt = 0;
GenLegal(boards[currentMove], PosFlags(currentMove), Mark, (void*) marker, EmptySquare);
if(PosFlags(0) & F_MANDATORY_CAPTURE) {
for(x=0; x<BOARD_WIDTH; x++) for(y=0; y<BOARD_HEIGHT; y++) if(marker[y][x] == 1) marker[y][x] = 0;
}
}
- DrawPosition(TRUE, NULL);
+ DrawPosition(FALSE, NULL);
}
int
{
int x, y;
Boolean saveAnimate;
- static int second = 0, promotionChoice = 0, clearFlag = 0;
+ static int second = 0, promotionChoice = 0, clearFlag = 0, sweepSelecting = 0;
char promoChoice = NULLCHAR;
ChessSquare piece;
static TimeMark lastClickTime, prevClickTime;
defaultPromoChoice = promoSweep;
promoSweep = EmptySquare; // terminate sweep
promoDefaultAltered = TRUE;
- if(!selectFlag && (x != toX || y != toY)) x = fromX, y = fromY; // and fake up-click on same square if we were still selecting
+ if(!selectFlag && !sweepSelecting && (x != toX || y != toY)) x = fromX, y = fromY; // and fake up-click on same square if we were still selecting
}
if(promotionChoice) { // we are waiting for a click to indicate promotion piece
}
if (appData.highlightDragging) {
SetHighlights(fromX, fromY, -1, -1);
+ } else {
+ ClearHighlights();
}
} else fromX = fromY = -1;
return;
/* Undo animation damage if any */
DrawPosition(FALSE, NULL);
}
- if (second) {
+ if (second || sweepSelecting) {
/* Second up/down in same square; just abort move */
- second = 0;
+ if(sweepSelecting) DrawPosition(FALSE, boards[currentMove]);
+ second = sweepSelecting = 0;
fromX = fromY = -1;
gatingPiece = EmptySquare;
ClearHighlights();
/* we now have a different from- and (possibly off-board) to-square */
/* Completed move */
- toX = x;
- toY = y;
- saveAnimate = appData.animate;
- MarkTargetSquares(1);
+ if(!sweepSelecting) {
+ toX = x;
+ toY = y;
+ saveAnimate = appData.animate;
+ } else sweepSelecting = 0; // this must be the up-click corresponding to the down-click that started the sweep
+
if (clickType == Press) {
if(gameMode == EditPosition && boards[currentMove][fromY][fromX] == EmptySquare) {
// must be Edit Position mode with empty-square selected
if(x >= BOARD_LEFT && x < BOARD_RGHT) clearFlag = 1; // and defer click-click move of empty-square to up-click
return;
}
- if(appData.sweepSelect && HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, FALSE)) {
+ if(HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, FALSE)) {
+ if(appData.sweepSelect) {
ChessSquare piece = boards[currentMove][fromY][fromX];
- DragPieceBegin(xPix, yPix, TRUE); dragging = 1;
promoSweep = defaultPromoChoice;
if(PieceToChar(PROMOTED piece) == '+') promoSweep = PROMOTED piece;
selectFlag = 0; lastX = xPix; lastY = yPix;
Sweep(0); // Pawn that is going to promote: preview promotion piece
+ sweepSelecting = 1;
DisplayMessage("", _("Pull pawn backwards to under-promote"));
- DrawPosition(FALSE, boards[currentMove]);
- return;
+ MarkTargetSquares(1);
+ }
+ return; // promo popup appears on up-click
}
/* Finish clickclick move */
if (appData.animate || appData.highlightLastMove) {
/* Don't animate move and drag both */
appData.animate = FALSE;
}
+ MarkTargetSquares(1);
// moves into holding are invalid for now (except in EditPosition, adapting to-square)
if(x >= 0 && x < BOARD_LEFT || x >= BOARD_RGHT) {
}
if (CheckFlags()) return;
+ if(twoBoards) { // count down secondary board's clocks as well
+ activePartnerTime -= lastTickLength;
+ partnerUp = 1;
+ if(activePartner == 'W')
+ DisplayWhiteClock(activePartnerTime, TRUE); // the counting clock is always the highlighted one!
+ else
+ DisplayBlackClock(activePartnerTime, TRUE);
+ partnerUp = 0;
+ }
+
tickStartTM = now;
intendedTickLength = NextTickLength(timeRemaining - fudge) + fudge;
StartClockTimer(intendedTickLength);