void ParseBoard12 P((char *string));
void KeepAlive P((void));
void StartClocks P((void));
-void SwitchClocks P((void));
+void SwitchClocks P((int nr));
void StopClocks P((void));
void ResetClocks P((void));
char *PGNDate P((void));
case VariantNoCastle:
case VariantShatranj:
case VariantCourier:
+ case VariantMakruk:
flags &= ~F_ALL_CASTLE_OK;
break;
default:
BlackUnicorn, BlackBishop, BlackMan, BlackRook }
};
-ChessSquare fairyArray[2][BOARD_SIZE] = { /* [HGM] Queen side differs from King side */
- { WhiteCannon, WhiteNightrider, WhiteAlfil, WhiteQueen,
+ChessSquare fairyArray[2][BOARD_SIZE] = { /* [HGM] white and black different armies! */
+ { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
- { BlackCannon, BlackNightrider, BlackAlfil, BlackQueen,
- BlackKing, BlackBishop, BlackKnight, BlackRook }
+ { BlackLance, BlackAlfil, BlackMarshall, BlackAngel,
+ BlackKing, BlackMarshall, BlackAlfil, BlackLance }
};
ChessSquare ShatranjArray[2][BOARD_SIZE] = { /* [HGM] (movGen knows about Shatranj Q and P) */
BlackFerz, BlackAlfil, BlackKnight, BlackRook }
};
+ChessSquare makrukArray[2][BOARD_SIZE] = { /* [HGM] (movGen knows about Shatranj Q and P) */
+ { WhiteRook, WhiteKnight, WhiteMan, WhiteKing,
+ WhiteFerz, WhiteMan, WhiteKnight, WhiteRook },
+ { BlackRook, BlackKnight, BlackMan, BlackFerz,
+ BlackKing, BlackMan, BlackKnight, BlackRook }
+};
+
#if (BOARD_SIZE>=10)
ChessSquare ShogiArray[2][BOARD_SIZE] = {
case VariantAtomic: /* should work except for win condition */
case Variant3Check: /* should work except for win condition */
case VariantShatranj: /* should work except for all win conditions */
+ case VariantMakruk: /* should work except for daw countdown */
case VariantBerolina: /* might work if TestLegality is off */
case VariantCapaRandom: /* should work */
case VariantJanus: /* should work */
looking_at(buf, &i, "It is not your move")) {
/* Illegal move */
if (ics_user_moved && forwardMostMove > backwardMostMove) { // only backup if we already moved
- currentMove = --forwardMostMove;
+ currentMove = forwardMostMove-1;
DisplayMove(currentMove - 1); /* before DMError */
DrawPosition(FALSE, boards[currentMove]);
- SwitchClocks();
+ SwitchClocks(forwardMostMove-1); // [HGM] race
DisplayBothClocks();
}
DisplayMoveError(_("Illegal move (rejected by ICS)")); // [HGM] but always relay error msg
case BlackPromotionChancellor:
case WhitePromotionArchbishop:
case BlackPromotionArchbishop:
- if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier)
+ if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk)
sprintf(user_move, "%c%c%c%c=%c\n",
AAA + fromX, ONE + fromY, AAA + toX, ONE + toY,
PieceToChar(WhiteFerz));
nrCastlingRights = 0;
SetCharTable(pieceToChar, "PN.R.QB...Kpn.r.qb...k");
break;
+ case VariantMakruk:
+ pieces = makrukArray;
+ nrCastlingRights = 0;
+ startedFromSetupPosition = TRUE;
+ SetCharTable(pieceToChar, "PN.R.M....SKpn.r.m....sk");
+ break;
case VariantTwoKings:
pieces = twoKingsArray;
break;
pawnRow = gameInfo.boardHeight - 7; /* seems to work in all common variants */
if(pawnRow < 1) pawnRow = 1;
+ if(gameInfo.variant == VariantMakruk) pawnRow = 2;
/* User pieceToChar list overrules defaults */
if(appData.pieceToCharTable != NULL)
if(gameInfo.variant == VariantShogi) {
promotionZoneSize = 3;
highestPromotingPiece = (int)WhiteFerz;
+ } else if(gameInfo.variant == VariantMakruk) {
+ promotionZoneSize = 3;
}
// next weed out all moves that do not touch the promotion zone at all
}
// we either have a choice what to promote to, or (in Shogi) whether to promote
- if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier) {
+ if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) {
*promoChoice = PieceToChar(BlackFerz); // no choice
return FALSE;
}
gameMode = EditGame;
ModeHighlight();
}
- currentMove = --forwardMostMove;
+ currentMove = forwardMostMove-1;
DisplayMove(currentMove-1); /* before DisplayMoveError */
- SwitchClocks();
+ SwitchClocks(forwardMostMove-1); // [HGM] race
DisplayBothClocks();
sprintf(buf1, _("Illegal move \"%s\" (rejected by %s chess program)"),
parseList[currentMove], cps->which);
char *ep;
{
ChessSquare captured = board[toY][toX], piece, king; int p, oldEP = EP_NONE, berolina = 0;
+ int promoRank = gameInfo.variant == VariantMakruk ? 3 : 1;
/* [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 */
}
/* [HGM] In Shatranj and Courier all promotions are to Ferz */
- if((gameInfo.variant==VariantShatranj || gameInfo.variant==VariantCourier)
+ if((gameInfo.variant==VariantShatranj || gameInfo.variant==VariantCourier || gameInfo.variant == VariantMakruk)
&& promoChar != 0) promoChar = PieceToChar(WhiteFerz);
if (fromX == toX && fromY == toY) return;
board[toY][toX+1] = board[fromY][BOARD_LEFT];
board[fromY][BOARD_LEFT] = EmptySquare;
} else if (board[fromY][fromX] == WhitePawn
- && toY == BOARD_HEIGHT-1
+ && toY >= BOARD_HEIGHT-promoRank
&& gameInfo.variant != VariantXiangqi
) {
/* white pawn promotion */
board[fromY][0] = EmptySquare;
board[toY][2] = BlackRook;
} else if (board[fromY][fromX] == BlackPawn
- && toY == 0
+ && toY < promoRank
&& gameInfo.variant != VariantXiangqi
) {
/* black pawn promotion */
- board[0][toX] = CharToPiece(ToLower(promoChar));
- if (board[0][toX] == EmptySquare) {
- board[0][toX] = BlackQueen;
+ board[toY][toX] = CharToPiece(ToLower(promoChar));
+ if (board[toY][toX] == EmptySquare) {
+ board[toY][toX] = BlackQueen;
}
if(gameInfo.variant==VariantBughouse ||
gameInfo.variant==VariantCrazyhouse) /* [HGM] use shadow piece */
{int i; for(i=0; i<BOARD_SIZE; i++) castlingRights[forwardMostMove+1][i] = castlingRights[forwardMostMove][i];}
ApplyMove(fromX, fromY, toX, toY, promoChar, boards[forwardMostMove+1],
castlingRights[forwardMostMove+1], &epStatus[forwardMostMove+1]);
- forwardMostMove++; // [HGM] bare: moved to after ApplyMove, to make sure clock interrupt finds complete board
- SwitchClocks(); // uses forwardMostMove, so must be done after incrementing it !
+ // forwardMostMove++; // [HGM] bare: moved to after ApplyMove, to make sure clock interrupt finds complete board
+ SwitchClocks(forwardMostMove+1); // [HGM] race: incrementing move nr inside
timeRemaining[0][forwardMostMove] = whiteTimeRemaining;
timeRemaining[1][forwardMostMove] = blackTimeRemaining;
gameInfo.result = GameUnfinished;
case BlackQueen:
if(gameInfo.variant == VariantShatranj ||
gameInfo.variant == VariantXiangqi ||
- gameInfo.variant == VariantCourier )
+ gameInfo.variant == VariantCourier ||
+ gameInfo.variant == VariantMakruk )
selection = (ChessSquare)((int)selection - (int)WhiteQueen + (int)WhiteFerz);
goto defaultlabel;
from the color that is *not* on move now.
*/
void
-SwitchClocks()
+SwitchClocks(int newMoveNr)
{
long lastTickLength;
TimeMark now;
if (StopClockTimer() && appData.clockMode) {
lastTickLength = SubtractTimeMarks(&now, &tickStartTM);
- if (WhiteOnMove(forwardMostMove)) {
+ if (!WhiteOnMove(forwardMostMove)) {
if(blackNPS >= 0) lastTickLength = 0;
blackTimeRemaining -= lastTickLength;
/* [HGM] PGNtime: save time for PGN file if engine did not give it */
}
flagged = CheckFlags();
}
+ forwardMostMove = newMoveNr; // [HGM] race: change stm when no timer interrupt scheduled
CheckTimeControl();
if (flagged || !appData.clockMode) return;
}
if(gameInfo.variant != VariantShogi && gameInfo.variant != VariantXiangqi &&
- gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier ) {
+ gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier && gameInfo.variant != VariantMakruk ) {
/* En passant target square */
if (move > backwardMostMove) {
fromX = moveList[move - 1][0] - AAA;
/* read e.p. field in games that know e.p. capture */
if(gameInfo.variant != VariantShogi && gameInfo.variant != VariantXiangqi &&
- gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier ) {
+ gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier && gameInfo.variant != VariantMakruk ) {
if(*p=='-') {
p++; FENepStatus = EP_NONE;
} else {