int LoadPositionFromFile P((char *filename, int n, char *title));\r
int SavePositionToFile P((char *filename));\r
void ApplyMove P((int fromX, int fromY, int toX, int toY, int promoChar,\r
- Board board));\r
+ Board board, char *castle, char *ep));\r
void MakeMove P((int fromX, int fromY, int toX, int toY, int promoChar));\r
void ShowMove P((int fromX, int fromY, int toX, int toY));\r
int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,\r
else strcpy(buf, str); // might be castling\r
if((prom = strstr(move_str, "=")) && !strstr(buf, "=")) \r
strcat(buf, prom); // long move lacks promo specification!\r
- if(!appData.testLegality) {\r
+ if(!appData.testLegality && move_str[1] != '@') { // drops never ambiguous (parser chokes on long form!)\r
if(appData.debugMode) \r
fprintf(debugFP, "replaced ICS move '%s' by '%s'\n", move_str, buf);\r
strcpy(move_str, buf);\r
* If they don't match, display an error message.\r
*/\r
int saveAnimate;\r
- Board testBoard;\r
+ Board testBoard; char testRights[BOARD_SIZE]; char testStatus;\r
CopyBoard(testBoard, boards[currentMove]);\r
- ApplyMove(fromX, fromY, toX, toY, promoChar, testBoard);\r
+ ApplyMove(fromX, fromY, toX, toY, promoChar, testBoard, testRights, &testStatus);\r
\r
if (CompareBoards(testBoard, boards[currentMove+1])) {\r
ForwardInner(currentMove+1);\r
\r
MakeMove(fromX, fromY, toX, toY, promoChar); /*updates forwardMostMove*/\r
\r
- if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) \r
- && promoChar != NULLCHAR && gameInfo.holdingsSize) { \r
- // [HGM] superchess: take promotion piece out of holdings\r
- int k = PieceToNumber(CharToPiece(ToUpper(promoChar)));\r
- if(WhiteOnMove(forwardMostMove-1)) {\r
- if(!--boards[forwardMostMove][k][BOARD_WIDTH-2])\r
- boards[forwardMostMove][k][BOARD_WIDTH-1] = EmptySquare;\r
- } else {\r
- if(!--boards[forwardMostMove][BOARD_HEIGHT-1-k][1])\r
- boards[forwardMostMove][BOARD_HEIGHT-1-k][0] = EmptySquare;\r
- }\r
- }\r
-\r
if (gameMode == BeginningOfGame) {\r
if (appData.noChessProgram) {\r
gameMode = EditGame;\r
EP_UNKNOWN, fromY, fromX, toY, toX, promoChar,\r
parseList[boardIndex]);\r
CopyBoard(boards[boardIndex + 1], boards[boardIndex]);\r
+ {int i; for(i=0; i<BOARD_SIZE; i++) castlingRights[boardIndex+1][i] = castlingRights[boardIndex][i];}\r
/* currentMoveString is set as a side-effect of yylex */\r
strcpy(moveList[boardIndex], currentMoveString);\r
strcat(moveList[boardIndex], "\n");\r
boardIndex++;\r
- ApplyMove(fromX, fromY, toX, toY, promoChar, boards[boardIndex]);\r
+ ApplyMove(fromX, fromY, toX, toY, promoChar, boards[boardIndex], \r
+ castlingRights[boardIndex], &epStatus[boardIndex]);\r
switch (MateTest(boards[boardIndex], PosFlags(boardIndex),\r
EP_UNKNOWN, castlingRights[boardIndex]) ) {\r
case MT_NONE:\r
\r
/* Apply a move to the given board */\r
void\r
-ApplyMove(fromX, fromY, toX, toY, promoChar, board)\r
+ApplyMove(fromX, fromY, toX, toY, promoChar, board, castling, ep)\r
int fromX, fromY, toX, toY;\r
int promoChar;\r
Board board;\r
+ char *castling;\r
+ char *ep;\r
{\r
ChessSquare captured = board[toY][toX], piece, king; int p, oldEP = EP_NONE, berolina = 0;\r
\r
/* [HGM] compute & store e.p. status and castling rights for new position */\r
- /* if we are updating a board for which those exist (i.e. in boards[]) */\r
- if((p = ((int)board - (int)boards[0])/((int)boards[1]-(int)boards[0])) < MAX_MOVES && p > 0)\r
+ /* we can always do that 'in place', now pointers to these rights are passed to ApplyMove */\r
{ int i;\r
\r
if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A;\r
- oldEP = epStatus[p-1];\r
- epStatus[p] = EP_NONE;\r
+ oldEP = *ep;\r
+ *ep = EP_NONE;\r
\r
if( board[toY][toX] != EmptySquare ) \r
- epStatus[p] = EP_CAPTURE; \r
+ *ep = EP_CAPTURE; \r
\r
if( board[fromY][fromX] == WhitePawn ) {\r
if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers\r
- epStatus[p] = EP_PAWN_MOVE;\r
+ *ep = EP_PAWN_MOVE;\r
if( toY-fromY==2) {\r
if(toX>BOARD_LEFT && board[toY][toX-1] == BlackPawn &&\r
gameInfo.variant != VariantBerolina || toX < fromX)\r
- epStatus[p] = toX | berolina;\r
+ *ep = toX | berolina;\r
if(toX<BOARD_RGHT-1 && board[toY][toX+1] == BlackPawn &&\r
gameInfo.variant != VariantBerolina || toX > fromX) \r
- epStatus[p] = toX;\r
+ *ep = toX;\r
}\r
} else \r
if( board[fromY][fromX] == BlackPawn ) {\r
if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers\r
- epStatus[p] = EP_PAWN_MOVE; \r
+ *ep = EP_PAWN_MOVE; \r
if( toY-fromY== -2) {\r
if(toX>BOARD_LEFT && board[toY][toX-1] == WhitePawn &&\r
gameInfo.variant != VariantBerolina || toX < fromX)\r
- epStatus[p] = toX | berolina;\r
+ *ep = toX | berolina;\r
if(toX<BOARD_RGHT-1 && board[toY][toX+1] == WhitePawn &&\r
gameInfo.variant != VariantBerolina || toX > fromX) \r
- epStatus[p] = toX;\r
+ *ep = toX;\r
}\r
}\r
\r
for(i=0; i<nrCastlingRights; i++) {\r
- castlingRights[p][i] = castlingRights[p-1][i];\r
- if(castlingRights[p][i] == fromX && castlingRank[i] == fromY ||\r
- castlingRights[p][i] == toX && castlingRank[i] == toY \r
- ) castlingRights[p][i] = -1; // revoke for moved or captured piece\r
+ if(castling[i] == fromX && castlingRank[i] == fromY ||\r
+ castling[i] == toX && castlingRank[i] == toY \r
+ ) castling[i] = -1; // revoke for moved or captured piece\r
}\r
\r
}\r
board[toY][toX] = (ChessSquare) (PROMOTED piece);\r
}\r
\r
+ if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) \r
+ && promoChar != NULLCHAR && gameInfo.holdingsSize) { \r
+ // [HGM] superchess: take promotion piece out of holdings\r
+ int k = PieceToNumber(CharToPiece(ToUpper(promoChar)));\r
+ if((int)piece < (int)BlackPawn) { // determine stm from piece color\r
+ if(!--board[k][BOARD_WIDTH-2])\r
+ board[k][BOARD_WIDTH-1] = EmptySquare;\r
+ } else {\r
+ if(!--board[BOARD_HEIGHT-1-k][1])\r
+ board[BOARD_HEIGHT-1-k][0] = EmptySquare;\r
+ }\r
+ }\r
+\r
}\r
\r
/* Updates forwardMostMove */\r
commentList[forwardMostMove+1] = NULL;\r
}\r
CopyBoard(boards[forwardMostMove+1], boards[forwardMostMove]);\r
- ApplyMove(fromX, fromY, toX, toY, promoChar, boards[forwardMostMove+1]);\r
+ {int i; for(i=0; i<BOARD_SIZE; i++) castlingRights[forwardMostMove+1][i] = castlingRights[forwardMostMove][i];}\r
+ ApplyMove(fromX, fromY, toX, toY, promoChar, boards[forwardMostMove+1], \r
+ castlingRights[forwardMostMove+1], &epStatus[forwardMostMove+1]);\r
forwardMostMove++; // [HGM] bare: moved to after ApplyMove, to make sure clock interrupt finds complete board\r
gameInfo.result = GameUnfinished;\r
if (gameInfo.resultDetails != NULL) {\r
WhiteOnMove(moveNumber) ? " " : ".. ",\r
parseList[moveNumber]);\r
}\r
+ // [HGM] PV info: display PV info together with (or as) comment\r
+ if(moveNumber >= 0 && (depth = pvInfoList[moveNumber].depth) > 0) {\r
+ if(text == NULL) text = ""; \r
+ score = pvInfoList[moveNumber].score;\r
+ sprintf(buf, "%s%.2f/%d %d\n%s", score>0 ? "+" : "", score/100.,\r
+ depth, (pvInfoList[moveNumber].time+50)/100, text);\r
+ text = buf;\r
+ }\r
} else title[0] = 0;\r
\r
- // [HGM] PV info: display PV info together with (or as) comment\r
- if(moveNumber >= 0 && (depth = pvInfoList[moveNumber].depth) > 0) {\r
- if(text == NULL) text = ""; \r
- score = pvInfoList[moveNumber].score;\r
- sprintf(buf, "%s%.2f/%d %d\n%s", score>0 ? "+" : "", score/100.,\r
- depth, (pvInfoList[moveNumber].time+50)/100, text);\r
- CommentPopUp(title, buf);\r
- } else\r
if (text != NULL)\r
CommentPopUp(title, text);\r
}\r