Send FICS atomic claim to ICS if move creates draw after offer
[xboard.git] / backend.c
index 0a7df47..d8c5410 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -167,6 +167,7 @@ int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,
                   /*char*/int promoChar));
 void BackwardInner P((int target));
 void ForwardInner P((int target));
+int Adjudicate P((ChessProgramState *cps));
 void GameEnds P((ChessMove result, char *resultDetails, int whosays));
 void EditPositionDone P((Boolean fakeRights));
 void PrintOpponents P((FILE *fp));
@@ -5461,8 +5462,6 @@ UserMoveTest(fromX, fromY, toX, toY, promoChar, captureOwn)
          return WhiteDrop; /* Not needed to specify white or black yet */
     }
 
-    userOfferedDraw = FALSE;
-       
     /* [HGM] always test for legality, to get promotion info */
     moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
                                          fromY, fromX, toY, toX, promoChar);
@@ -5577,6 +5576,8 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
 
   MakeMove(fromX, fromY, toX, toY, promoChar); /*updates forwardMostMove*/
 
+  if(Adjudicate(NULL)) return 1; // [HGM] adjudicate: take care of automtic game end
+
   if (gameMode == BeginningOfGame) {
     if (appData.noChessProgram) {
       gameMode = EditGame;
@@ -5601,6 +5602,12 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
   if (appData.icsActive) {
     if (gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||
        gameMode == IcsExamining) {
+      if(userOfferedDraw && (signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
+        SendToICS(ics_prefix); // [HGM] drawclaim: send caim and move on one line for FICS
+       SendToICS("draw ");
+        SendMoveToICS(moveType, fromX, fromY, toX, toY);
+      }
+      // also send plain move, in case ICS does not understand atomic claims
       SendMoveToICS(moveType, fromX, fromY, toX, toY);
       ics_user_moved = 1;
     }
@@ -5652,6 +5659,8 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
     break;
   }
 
+  userOfferedDraw = FALSE; // [HGM] drawclaim: after move made, and tested for claimable draw
+       
   if(bookHit) { // [HGM] book: simulate book reply
        static char bookMove[MSG_SIZ]; // a bit generous?
 
@@ -6281,8 +6290,7 @@ Adjudicate(ChessProgramState *cps)
                  * claim draws before making their move to avoid a race
                  * condition occurring after their move
                  */
-               if(gameMode == TwoMachinesPlay) // for now; figure out how to handle claims in human games
-                if( cps->other->offeredDraw || cps->offeredDraw ) {
+               if((gameMode == TwoMachinesPlay ? second.offeredDraw : userOfferedDraw) || first.offeredDraw ) {
                          char *p = NULL;
                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_RULE_DRAW)
                              p = "Draw claim: 50-move rule";
@@ -6290,7 +6298,7 @@ Adjudicate(ChessProgramState *cps)
                              p = "Draw claim: 3-fold repetition";
                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_INSUF_DRAW)
                              p = "Draw claim: insufficient mating material";
-                         if( p != NULL ) {
+                         if( p != NULL && canAdjudicate) {
                             if(engineOpponent) {
                               SendToProgram("force\n", engineOpponent); // suppress reply
                               SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
@@ -11787,6 +11795,7 @@ DrawEvent()
        
         SendToICS(ics_prefix);
        SendToICS("draw\n");
+        userOfferedDraw = TRUE; // [HGM] drawclaim: also set flag in ICS play
     } else if (cmailMsgLoaded) {
        if (currentMove == cmailOldMove &&
            commentList[cmailOldMove] != NULL &&