}
}
if(chattingPartner<0) // if not, look if there is a chatbox for this indivdual
- for(p=0; p<MAX_CHAT; p++) if(!strcasecmp(talker+1, chatPartner[p])) {
+ for(p=0; p<MAX_CHAT; p++) if(!StrCaseCmp(talker+1, chatPartner[p])) {
talker[0] = 0;
chattingPartner = p; break;
}
oldh = gameInfo.holdingsWidth,
oldv = gameInfo.variant;
- currentMove = forwardMostMove = backwardMostMove = 0;
if(appData.icsActive) shuffleOpenings = FALSE; // [HGM] shuffle: in ICS mode, only shuffle on ICS request
/* [AS] Initialize pv info list [HGM] and game status */
ChessMove
-UserMoveTest(fromX, fromY, toX, toY, promoChar)
+UserMoveTest(fromX, fromY, toX, toY, promoChar, captureOwn)
int fromX, fromY, toX, toY;
int promoChar;
+ Boolean captureOwn;
{
ChessMove moveType;
ChessSquare pdown, pup;
if (fromX < 0 || fromY < 0) return ImpossibleMove;
- if ((fromX == toX) && (fromY == toY)) {
- return ImpossibleMove;
- }
/* [HGM] suppress all moves into holdings area and guard band */
if( toX < BOARD_LEFT || toX >= BOARD_RGHT || toY < 0 )
return ImpossibleMove;
/* [HGM] <sameColor> moved to here from winboard.c */
- /* note: this code seems to exist for filtering out some obviously illegal premoves */
+ /* note: capture of own piece can be legal as drag-drop premove. For click-click it is selection of new piece. */
pdown = boards[currentMove][fromY][fromX];
pup = boards[currentMove][toY][toX];
- if ( gameMode != EditPosition &&
+ if ( gameMode != EditPosition && !captureOwn &&
(WhitePawn <= pdown && pdown < BlackPawn &&
WhitePawn <= pup && pup < BlackPawn ||
BlackPawn <= pdown && pdown < EmptySquare &&
BlackPawn <= pup && pup < EmptySquare
) && !((gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom) &&
(pup == WhiteRook && pdown == WhiteKing && fromY == 0 && toY == 0||
- pup == BlackRook && pdown == BlackKing && fromY == BOARD_HEIGHT-1 && toY == BOARD_HEIGHT-1 )
+ pup == BlackRook && pdown == BlackKing && fromY == BOARD_HEIGHT-1 && toY == BOARD_HEIGHT-1 ||
+ pup == WhiteKing && pdown == WhiteRook && fromY == 0 && toY == 0|| // also allow RxK
+ pup == BlackKing && pdown == BlackRook && fromY == BOARD_HEIGHT-1 && toY == BOARD_HEIGHT-1 )
) )
- return ImpossibleMove;
+ return Comment;
/* Check if the user is playing in turn. This is complicated because we
let the user "pick up" a piece before it is his turn. So the piece he
fprintf(debugFP, "Got premove: fromX %d,"
"fromY %d, toX %d, toY %d\n",
fromX, fromY, toX, toY);
+ if(!WhiteOnMove(currentMove) && gotPremove == 1) {
+ // [HGM] race: we must have been hit by an opponent move from the ICS while preparing the premove
+ if (appData.debugMode)
+ fprintf(debugFP, "Execute as normal move\n");
+ gotPremove = 0; break;
+ }
}
return ImpossibleMove;
}
fprintf(debugFP, "Got premove: fromX %d,"
"fromY %d, toX %d, toY %d\n",
fromX, fromY, toX, toY);
+ if(WhiteOnMove(currentMove) && gotPremove == 1) {
+ // [HGM] race: we must have been hit by an opponent move from the ICS while preparing the premove
+ if (appData.debugMode)
+ fprintf(debugFP, "Execute as normal move\n");
+ gotPremove = 0; break;
+ }
}
return ImpossibleMove;
}
moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
epStatus[currentMove], castlingRights[currentMove],
fromY, fromX, toY, toX, promoChar);
-
/* [HGM] but possibly ignore an IllegalMove result */
if (appData.testLegality) {
if (moveType == IllegalMove || moveType == ImpossibleMove) {
FinishMove if the first part succeeded. Calls that do not need
to do anything in between, can call this routine the old way.
*/
- ChessMove moveType = UserMoveTest(fromX, fromY, toX, toY, promoChar);
+ ChessMove moveType = UserMoveTest(fromX, fromY, toX, toY, promoChar, FALSE);
if(appData.debugMode) fprintf(debugFP, "moveType 4 = %d, promochar = %x\n", moveType, promoChar);
if(moveType == AmbiguousMove)
DrawPosition(FALSE, boards[currentMove]);
- else if(moveType != ImpossibleMove)
+ else if(moveType != ImpossibleMove && moveType != Comment)
FinishMove(moveType, fromX, fromY, toX, toY, promoChar);
}
}
#endif
if (pausing) PauseEvent();
+ if(appData.forceIllegal) {
+ // [HGM] illegal: machine refused move; force position after move into it
+ SendToProgram("force\n", cps);
+ if(!cps->useSetboard) { // hideous kludge on kludge, because SendBoard sucks.
+ // we have a real problem now, as SendBoard will use the a2a3 kludge
+ // when black is to move, while there might be nothing on a2 or black
+ // might already have the move. So send the board as if white has the move.
+ // But first we must change the stm of the engine, as it refused the last move
+ SendBoard(cps, 0); // always kludgeless, as white is to move on boards[0]
+ if(WhiteOnMove(forwardMostMove)) {
+ SendToProgram("a7a6\n", cps); // for the engine black still had the move
+ SendBoard(cps, forwardMostMove); // kludgeless board
+ } else {
+ SendToProgram("a2a3\n", cps); // for the engine white still had the move
+ CopyBoard(boards[forwardMostMove+1], boards[forwardMostMove]);
+ SendBoard(cps, forwardMostMove+1); // kludgeless board
+ }
+ } else SendBoard(cps, forwardMostMove); // FEN case, also sets stm properly
+ if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack ||
+ gameMode == TwoMachinesPlay)
+ SendToProgram("go\n", cps);
+ return;
+ } else
if (gameMode == PlayFromGameFile) {
/* Stop reading this game file */
gameMode = EditGame;
gameMode = BeginningOfGame;
ModeHighlight();
if(appData.icsActive) gameInfo.variant = VariantNormal;
+ currentMove = forwardMostMove = backwardMostMove = 0;
InitPosition(redraw);
for (i = 0; i < MAX_MOVES; i++) {
if (commentList[i] != NULL) {