fix for new way of saving castling and e.p. information
authorH.G. Muller <h.g.muller@hccnet.nl>
Fri, 6 Nov 2009 16:48:09 +0000 (08:48 -0800)
committerArun Persaud <arun@nubati.net>
Fri, 6 Nov 2009 16:54:26 +0000 (08:54 -0800)
I forgot to make some conversions to the new-style encoding of castling there
(using the enum constant NoRights instead of -1 to indicate
the absence of rights, which was the price of storing the
rights in the board, which is an unsigned enum type.)

I also was a bit worried about portability, because I casted the enum type ChessSquare
to (int) before comparing it with (possibly negative) constants EP_NONE etc.
Now on my system enum types are (unsigned int), and this works, but I could
imagine there are systems where this would be an unsigned char. (Not sure
if there are rules for this). So to be safe I cast ChessSquare to (signed char),
which should always work to make small negative ints assigned to it read
back as themselves.

backend.c
moves.c

index 7f8db9e..c4e9316 100755 (executable)
--- a/backend.c
+++ b/backend.c
@@ -2304,7 +2304,7 @@ read_from_ics(isr, closure, data, count, error)
                        chattingPartner = -1;
                    } else
                    if(!suppressKibitz) // [HGM] kibitz
-                       AppendComment(forwardMostMove, StripHighlight(parse));
+                       AppendComment(forwardMostMove, StripHighlight(parse), TRUE);
                    else { // [HGM kibitz: divert memorized engine kibitz to engine-output window
                        int nrDigit = 0, nrAlph = 0, i;
                        if(parse_pos > MSG_SIZ - 30) // defuse unreasonably long input
@@ -6145,7 +6145,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
              case MT_STALEMATE:
              case MT_STAINMATE:
                reason = "Xboard adjudication: Stalemate";
-               if((int)boards[forwardMostMove][EP_STATUS] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
+               if((signed char)boards[forwardMostMove][EP_STATUS] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
                    boards[forwardMostMove][EP_STATUS] = EP_STALEMATE;   // default result for stalemate is draw
                    if(gameInfo.variant == VariantLosers  || gameInfo.variant == VariantGiveaway) // [HGM] losers:
                        boards[forwardMostMove][EP_STATUS] = EP_WINS;    // in these variants stalemated is always a win
@@ -6163,7 +6163,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                break;
            }
 
-               switch(i = (int)boards[forwardMostMove][EP_STATUS]) {
+               switch(i = (signed char)boards[forwardMostMove][EP_STATUS]) {
                    case EP_STALEMATE:
                        result = GameIsDrawn; break;
                    case EP_CHECKMATE:
@@ -6224,7 +6224,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                    forwardMostMove, backwardMostMove, boards[backwardMostMove][EP_STATUS],
                    appData.drawRepeats);
            for( i=forwardMostMove; i>=backwardMostMove; i-- )
-             fprintf(debugFP, "%d ep=%d\n", i, (int)boards[i][EP_STATUS]);
+             fprintf(debugFP, "%d ep=%d\n", i, (signed char)boards[i][EP_STATUS]);
            
          }
 
@@ -6232,8 +6232,8 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                 count = 0;
                 for(k = forwardMostMove-2;
                     k>=backwardMostMove && k>=forwardMostMove-100 &&
-                        (int)boards[k][EP_STATUS] < EP_UNKNOWN &&
-                        (int)boards[k+2][EP_STATUS] <= EP_NONE && (int)boards[k+1][EP_STATUS] <= EP_NONE;
+                        (signed char)boards[k][EP_STATUS] < EP_UNKNOWN &&
+                        (signed char)boards[k+2][EP_STATUS] <= EP_NONE && (signed char)boards[k+1][EP_STATUS] <= EP_NONE;
                     k-=2)
                 {   int rights=0;
                     if(CompareBoards(boards[k], boards[forwardMostMove])) {
@@ -6303,7 +6303,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                 /* Now we test for 50-move draws. Determine ply count */
                 count = forwardMostMove;
                 /* look for last irreversble move */
-                while( (int)boards[count][EP_STATUS] <= EP_NONE && count > backwardMostMove )
+                while( (signed char)boards[count][EP_STATUS] <= EP_NONE && count > backwardMostMove )
                     count--;
                 /* if we hit starting position, add initial plies */
                 if( count == backwardMostMove )
@@ -6327,11 +6327,11 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                  */
                 if( cps->other->offeredDraw || cps->offeredDraw ) {
                          char *p = NULL;
-                         if((int)boards[forwardMostMove][EP_STATUS] == EP_RULE_DRAW)
+                         if((signed char)boards[forwardMostMove][EP_STATUS] == EP_RULE_DRAW)
                              p = "Draw claim: 50-move rule";
-                         if((int)boards[forwardMostMove][EP_STATUS] == EP_REP_DRAW)
+                         if((signed char)boards[forwardMostMove][EP_STATUS] == EP_REP_DRAW)
                              p = "Draw claim: 3-fold repetition";
-                         if((int)boards[forwardMostMove][EP_STATUS] == EP_INSUF_DRAW)
+                         if((signed char)boards[forwardMostMove][EP_STATUS] == EP_INSUF_DRAW)
                              p = "Draw claim: insufficient mating material";
                          if( p != NULL ) {
                             SendToProgram("force\n", cps->other); // suppress reply
@@ -7343,7 +7343,7 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board)
     { int i;
 
       if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A;
-      oldEP = board[EP_STATUS];
+      oldEP = (signed char)board[EP_STATUS];
       board[EP_STATUS] = EP_NONE;
 
       if( board[toY][toX] != EmptySquare ) 
@@ -8110,15 +8110,15 @@ GameEnds(result, resultDetails, whosays)
                                             second.twoMachinesColor[0] ;
 
                // [HGM] losers: because the logic is becoming a bit hairy, determine true result first
-               if((int)boards[forwardMostMove][EP_STATUS] == EP_CHECKMATE) {
+               if((signed char)boards[forwardMostMove][EP_STATUS] == EP_CHECKMATE) {
                    /* [HGM] verify: engine mate claims accepted if they were flagged */
                    trueResult = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins;
                } else
-               if((int)boards[forwardMostMove][EP_STATUS] == EP_WINS) { // added code for games where being mated is a win
+               if((signed char)boards[forwardMostMove][EP_STATUS] == EP_WINS) { // added code for games where being mated is a win
                    /* [HGM] verify: engine mate claims accepted if they were flagged */
                    trueResult = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins;
                } else
-               if((int)boards[forwardMostMove][EP_STATUS] == EP_STALEMATE) { // only used to indicate draws now
+               if((signed char)boards[forwardMostMove][EP_STATUS] == EP_STALEMATE) { // only used to indicate draws now
                    trueResult = GameIsDrawn; // default; in variants where stalemate loses, Status is CHECKMATE
                }
 
@@ -8129,7 +8129,7 @@ GameEnds(result, resultDetails, whosays)
                      result == BlackWins && claimer == 'b'   ) ) { // case to verify: engine claims own win
                      if (appData.debugMode) {
                        fprintf(debugFP, "result=%d sp=%d move=%d\n",
-                               result, (int)boards[forwardMostMove][EP_STATUS], forwardMostMove);
+                               result, (signed char)boards[forwardMostMove][EP_STATUS], forwardMostMove);
                      }
                      if(result != trueResult) {
                              sprintf(buf, "False win claim: '%s'", resultDetails);
@@ -8137,9 +8137,9 @@ GameEnds(result, resultDetails, whosays)
                              resultDetails = buf;
                      }
                 } else
-                if( result == GameIsDrawn && (int)boards[forwardMostMove][EP_STATUS] > EP_DRAWS
+                if( result == GameIsDrawn && (signed char)boards[forwardMostMove][EP_STATUS] > EP_DRAWS
                     && (forwardMostMove <= backwardMostMove ||
-                        (int)boards[forwardMostMove-1][EP_STATUS] > EP_DRAWS ||
+                        (signed char)boards[forwardMostMove-1][EP_STATUS] > EP_DRAWS ||
                         (claimer=='b')==(forwardMostMove&1))
                                                                                   ) {
                       /* [HGM] verify: draws that were not flagged are false claims */
@@ -8156,7 +8156,7 @@ GameEnds(result, resultDetails, whosays)
               && result != GameIsDrawn)
            {   int i, j, k=0, color = (result==WhiteWins ? (int)WhitePawn : (int)BlackPawn);
                for(j=BOARD_LEFT; j<BOARD_RGHT; j++) for(i=0; i<BOARD_HEIGHT; i++) {
-                       int p = (int)boards[forwardMostMove][i][j] - color;
+                       int p = (signed char)boards[forwardMostMove][i][j] - color;
                        if(p >= 0 && p <= (int)WhiteKing) k++;
                }
                if (appData.debugMode) {
@@ -8635,14 +8635,9 @@ LoadGameOneMove(readAhead)
        if (appData.debugMode) 
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
-       if (*p == '{' || *p == '[' || *p == '(') {
-           p[strlen(p) - 1] = NULLCHAR;
-           p++;
-       }
 
        /* append the comment but don't display it */
-       while (*p == '\n') p++;
-       AppendComment(currentMove, p);
+       AppendComment(currentMove, p, FALSE);
        return TRUE;
 
       case WhiteCapturesEnPassant:
@@ -9310,12 +9305,7 @@ LoadGame(f, gameNumber, title, useList)
            if (appData.debugMode) 
              fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
            p = yy_text;
-           if (*p == '{' || *p == '[' || *p == '(') {
-               p[strlen(p) - 1] = NULLCHAR;
-               p++;
-           }
-           while (*p == '\n') p++;
-           AppendComment(currentMove, p);
+           AppendComment(currentMove, p, FALSE);
            yyboardindex = forwardMostMove;
            cm = (ChessMove) yylex();
        }
@@ -9416,12 +9406,7 @@ LoadGame(f, gameNumber, title, useList)
        if (appData.debugMode) 
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
-       if (*p == '{' || *p == '[' || *p == '(') {
-           p[strlen(p) - 1] = NULLCHAR;
-           p++;
-       }
-       while (*p == '\n') p++;
-       AppendComment(currentMove, p);
+       AppendComment(currentMove, p, FALSE);
        yyboardindex = forwardMostMove;
        cm = (ChessMove) yylex();
     }
@@ -9867,7 +9852,7 @@ SaveGamePGN(f)
        /* Print comments preceding this move */
        if (commentList[i] != NULL) {
            if (linelen > 0) fprintf(f, "\n");
-           fprintf(f, "{\n%s}\n", commentList[i]);
+           fprintf(f, "%s\n", commentList[i]);
            linelen = 0;
            newblock = TRUE;
        }
@@ -9970,7 +9955,7 @@ SaveGamePGN(f)
 
     /* Print comments after last move */
     if (commentList[i] != NULL) {
-       fprintf(f, "{\n%s}\n", commentList[i]);
+       fprintf(f, "%s\n", commentList[i]);
     }
 
     /* Print result */
@@ -11442,7 +11427,7 @@ DeclineEvent()
            StrStr(commentList[cmailOldMove], WhiteOnMove(cmailOldMove) ?
                   "Black offers a draw" : "White offers a draw")) {
 #ifdef NOTDEF
-           AppendComment(cmailOldMove, "Draw declined");
+           AppendComment(cmailOldMove, "Draw declined", TRUE);
            DisplayComment(cmailOldMove - 1, "Draw declined");
 #endif /*NOTDEF*/
        } else {
@@ -11524,7 +11509,7 @@ DrawEvent()
        } else if (currentMove == cmailOldMove + 1) {
            char *offer = WhiteOnMove(cmailOldMove) ?
              "White offers a draw" : "Black offers a draw";
-           AppendComment(currentMove, offer);
+           AppendComment(currentMove, offer, TRUE);
            DisplayComment(currentMove - 1, offer);
            cmailMoveType[lastLoadGameNumber - 1] = CMAIL_DRAW;
        } else {
@@ -12201,10 +12186,20 @@ ReplaceComment(index, text)
        commentList[index] = NULL;
        return;
     }
+  if(*text == '{' || *text == '(' || *text == '[') {
     commentList[index] = (char *) malloc(len + 2);
     strncpy(commentList[index], text, len);
     commentList[index][len] = '\n';
     commentList[index][len + 1] = NULLCHAR;
+  } else { 
+    // [HGM] braces: if text does not start with known OK delimiter, put braces around it.
+    char *p;
+    commentList[index] = (char *) malloc(len + 6);
+    strcpy(commentList[index], "{\n");
+    strcat(commentList[index], text);
+    while(p = strchr(commentList[index], '}')) *p = ')'; // kill all } to make it one comment
+    strcat(commentList[index], "\n}");
+  }
 }
 
 void
@@ -12223,13 +12218,15 @@ CrushCRs(text)
 }
 
 void
-AppendComment(index, text)
+AppendComment(index, text, addBraces)
      int index;
      char *text;
+     Boolean addBraces; // [HGM] braces: tells if we should add {}
 {
     int oldlen, len;
     char *old;
 
+if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces); fflush(debugFP);
     text = GetInfoFromComment( index, text ); /* [HGM] PV time: strip PV info from comment */
 
     CrushCRs(text);
@@ -12242,17 +12239,25 @@ AppendComment(index, text)
     if (commentList[index] != NULL) {
        old = commentList[index];
        oldlen = strlen(old);
-       commentList[index] = (char *) malloc(oldlen + len + 2);
+       commentList[index] = (char *) malloc(oldlen + len + 4); // might waste 2
        strcpy(commentList[index], old);
        free(old);
+       // [HGM] braces: join "{A\n}" + "{B}" as "{A\nB\n}"
+       if(commentList[index][oldlen-1] == '}' && (text[0] == '{' || addBraces)) {
+         if(addBraces) addBraces = FALSE; else { text++; len--; }
+         while (*text == '\n') { text++; len--; }
+         commentList[index][oldlen-1] = NULLCHAR;
+         oldlen--;
+      }
        strncpy(&commentList[index][oldlen], text, len);
-       commentList[index][oldlen + len] = '\n';
-       commentList[index][oldlen + len + 1] = NULLCHAR;
+       if(addBraces) strcpy(&commentList[index][oldlen + len], "\n}");
+       else          strcpy(&commentList[index][oldlen + len], "\n");
     } else {
-       commentList[index] = (char *) malloc(len + 2);
-       strncpy(commentList[index], text, len);
-       commentList[index][len] = '\n';
-       commentList[index][len + 1] = NULLCHAR;
+       commentList[index] = (char *) malloc(len + 4); // perhaps wastes 2...
+       if(addBraces) commentList[index][0] = '{';
+       strcpy(commentList[index] + addBraces, text);
+       strcat(commentList[index], "\n");
+       if(addBraces) strcat(commentList[index], "}");
     }
 }
 
@@ -12296,21 +12301,24 @@ char *GetInfoFromComment( int index, char * text )
 
             if( s_emt != NULL ) {
             }
+               return text;
         }
         else {
             /* We expect something like: [+|-]nnn.nn/dd */
             int score_lo = 0;
 
+            if(*text != '{') return text; // [HGM] braces: must be normal comment
+
             sep = strchr( text, '/' );
             if( sep == NULL || sep < (text+4) ) {
                 return text;
             }
 
             time = -1; sec = -1; deci = -1;
-            if( sscanf( text, "%d.%d/%d %d:%d", &score, &score_lo, &depth, &time, &sec ) != 5 &&
-               sscanf( text, "%d.%d/%d %d.%d", &score, &score_lo, &depth, &time, &deci ) != 5 &&
-                sscanf( text, "%d.%d/%d %d", &score, &score_lo, &depth, &time ) != 4 &&
-                sscanf( text, "%d.%d/%d", &score, &score_lo, &depth ) != 3   ) {
+            if( sscanf( text+1, "%d.%d/%d %d:%d", &score, &score_lo, &depth, &time, &sec ) != 5 &&
+               sscanf( text+1, "%d.%d/%d %d.%d", &score, &score_lo, &depth, &time, &deci ) != 5 &&
+                sscanf( text+1, "%d.%d/%d %d", &score, &score_lo, &depth, &time ) != 4 &&
+                sscanf( text+1, "%d.%d/%d", &score, &score_lo, &depth ) != 3   ) {
                 return text;
             }
 
@@ -12345,6 +12353,7 @@ char *GetInfoFromComment( int index, char * text )
         pvInfoList[index-1].depth = depth;
         pvInfoList[index-1].score = score;
         pvInfoList[index-1].time  = 10*time; // centi-sec
+        if(*sep == '}') *sep = 0; else *--sep = '{';
     }
     return sep;
 }
@@ -12374,7 +12383,7 @@ SendToProgram(message, cps)
                          && !endingGame) { /* [HGM] crash: to not hang GameEnds() writing to deceased engines */
        sprintf(buf, _("Error writing to %s chess program"), cps->which);
         if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */
-            if((int)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
+            if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
                 gameInfo.result = GameIsDrawn; /* [HGM] accept exit as draw claim */
                 sprintf(buf, "%s program exits in draw position (%s)", cps->which, cps->program);
             } else {
@@ -12405,7 +12414,7 @@ ReceiveFromProgram(isr, closure, message, count, error)
                    _("Error: %s chess program (%s) exited unexpectedly"),
                    cps->which, cps->program);
         if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */
-                if((int)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
+                if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
                     gameInfo.result = GameIsDrawn; /* [HGM] accept exit as draw claim */
                     sprintf(buf, _("%s program exits in draw position (%s)"), cps->which, cps->program);
                 } else {
@@ -13718,7 +13727,7 @@ PositionToFEN(move, overrideCastling)
        }
     } else if(move == backwardMostMove) {
        // [HGM] perhaps we should always do it like this, and forget the above?
-       if((int)boards[move][EP_STATUS] >= 0) {
+       if((signed char)boards[move][EP_STATUS] >= 0) {
            *p++ = boards[move][EP_STATUS] + AAA;
            *p++ = whiteToPlay ? '6'+BOARD_HEIGHT-8 : '3';
        } else {
@@ -13737,11 +13746,11 @@ PositionToFEN(move, overrideCastling)
         if (appData.debugMode) { int k;
             fprintf(debugFP, "write FEN 50-move: %d %d %d\n", initialRulePlies, forwardMostMove, backwardMostMove);
             for(k=backwardMostMove; k<=forwardMostMove; k++)
-                fprintf(debugFP, "e%d. p=%d\n", k, (int)boards[k][EP_STATUS]);
+                fprintf(debugFP, "e%d. p=%d\n", k, (signed char)boards[k][EP_STATUS]);
 
         }
 
-        while(j > backwardMostMove && (int)boards[j][EP_STATUS] <= EP_NONE) j--,i++;
+        while(j > backwardMostMove && (signed char)boards[j][EP_STATUS] <= EP_NONE) j--,i++;
         if( j == backwardMostMove ) i += initialRulePlies;
         sprintf(p, "%d ", i);
         p += i>=100 ? 4 : i >= 10 ? 3 : 2;
diff --git a/moves.c b/moves.c
index 9086a92..12f9b63 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -262,7 +262,7 @@ void GenPseudoLegal(board, flags, callback, closure)
 {
     int rf, ff;
     int i, j, d, s, fs, rs, rt, ft, m;
-    int epfile = board[EP_STATUS]; // [HGM] gamestate: extract ep status from board
+    int epfile = (signed char)board[EP_STATUS]; // [HGM] gamestate: extract ep status from board
 
     for (rf = 0; rf < BOARD_HEIGHT; rf++) 
       for (ff = BOARD_LEFT; ff < BOARD_RGHT; ff++) {
@@ -783,7 +783,7 @@ int GenLegal(board, flags, callback, closure)
             board[0][BOARD_RGHT-3] == EmptySquare &&
             board[0][BOARD_RGHT-2] == EmptySquare &&
             board[0][BOARD_RGHT-1] == WhiteRook &&
-            (int)castlingRights[0] >= 0 && /* [HGM] check rights */
+            castlingRights[0] != NoRights && /* [HGM] check rights */
             ( castlingRights[2] == ff || castlingRights[6] == ff ) &&
             (ignoreCheck ||                             
             (!CheckTest(board, flags, 0, ff, 0, ff + 1, FALSE) &&
@@ -803,7 +803,7 @@ int GenLegal(board, flags, callback, closure)
             board[0][BOARD_LEFT+2] == EmptySquare &&
             board[0][BOARD_LEFT+1] == EmptySquare &&
             board[0][BOARD_LEFT+0] == WhiteRook &&
-            (int)castlingRights[1] >= 0 && /* [HGM] check rights */
+            castlingRights[1] != NoRights && /* [HGM] check rights */
             ( castlingRights[2] == ff || castlingRights[6] == ff ) &&
            (ignoreCheck ||
             (!CheckTest(board, flags, 0, ff, 0, ff - 1, FALSE) &&
@@ -822,7 +822,7 @@ int GenLegal(board, flags, callback, closure)
             board[BOARD_HEIGHT-1][BOARD_RGHT-3] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_RGHT-2] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook &&
-            (int)castlingRights[3] >= 0 && /* [HGM] check rights */
+            castlingRights[3] != NoRights && /* [HGM] check rights */
             ( castlingRights[5] == ff || castlingRights[7] == ff ) &&
            (ignoreCheck ||
             (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 1, FALSE) &&
@@ -842,7 +842,7 @@ int GenLegal(board, flags, callback, closure)
             board[BOARD_HEIGHT-1][BOARD_LEFT+2] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_LEFT+1] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_LEFT+0] == BlackRook &&
-            (int)castlingRights[4] >= 0 && /* [HGM] check rights */
+            castlingRights[4] != NoRights && /* [HGM] check rights */
             ( castlingRights[5] == ff || castlingRights[7] == ff ) &&
            (ignoreCheck ||
             (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 1, FALSE) &&
@@ -863,7 +863,7 @@ int GenLegal(board, flags, callback, closure)
 
     if ((flags & F_WHITE_ON_MOVE) != 0) {
         ff = castlingRights[2]; /* King file if we have any rights */
-        if(ff > 0 && board[0][ff] == WhiteKing) {
+        if(ff != NoRights && board[0][ff] == WhiteKing) {
     if (appData.debugMode) {
         fprintf(debugFP, "FRC castling, %d %d %d %d %d %d\n",
                 castlingRights[0],castlingRights[1],ff,castlingRights[3],castlingRights[4],castlingRights[5]);
@@ -872,49 +872,49 @@ int GenLegal(board, flags, callback, closure)
             left  = ff+1;
             right = BOARD_RGHT-2;
             if(ff == BOARD_RGHT-2) left = right = ff-1;    /* special case */
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[0][k] != EmptySquare) ft = -1;
-            for(k=left; k<right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[0][ft] == WhiteRook)
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[0][k] != EmptySquare) ft = NoRights;
+            for(k=left; k<right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[0][ft] == WhiteRook)
                 callback(board, flags, WhiteHSideCastleFR, 0, ff, 0, ft, closure);
 
             ft = castlingRights[1]; /* Rook file if we have A-side rights */
             left  = BOARD_LEFT+2;
             right = ff-1;
             if(ff <= BOARD_LEFT+2) { left = ff+1; right = BOARD_LEFT+3; }
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[0][k] != EmptySquare) ft = -1;
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[0][k] != EmptySquare) ft = NoRights;
             if(ff > BOARD_LEFT+2) 
-            for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[0][ft] == WhiteRook)
+            for(k=left+1; k<=right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[0][ft] == WhiteRook)
                 callback(board, flags, WhiteASideCastleFR, 0, ff, 0, ft, closure);
         }
     } else {
         ff = castlingRights[5]; /* King file if we have any rights */
-        if(ff > 0 && board[BOARD_HEIGHT-1][ff] == BlackKing) {
+        if(ff != NoRights && board[BOARD_HEIGHT-1][ff] == BlackKing) {
             ft = castlingRights[3]; /* Rook file if we have H-side rights */
             left  = ff+1;
             right = BOARD_RGHT-2;
             if(ff == BOARD_RGHT-2) left = right = ff-1;    /* special case */
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1;
-            for(k=left; k<right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = NoRights;
+            for(k=left; k<right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[BOARD_HEIGHT-1][ft] == BlackRook)
                 callback(board, flags, BlackHSideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);
 
             ft = castlingRights[4]; /* Rook file if we have A-side rights */
             left  = BOARD_LEFT+2;
             right = ff-1;
             if(ff <= BOARD_LEFT+2) { left = ff+1; right = BOARD_LEFT+3; }
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1;
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = NoRights;
             if(ff > BOARD_LEFT+2) 
-            for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)
+            for(k=left+1; k<=right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[BOARD_HEIGHT-1][ft] == BlackRook)
                 callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);
         }
     }