From: H.G. Muller Date: Fri, 6 Nov 2009 16:48:09 +0000 (-0800) Subject: fix for new way of saving castling and e.p. information X-Git-Tag: master-20091122~16 X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=941395daf4333598be57255c9b722c7c09b3adf3;p=xboard.git fix for new way of saving castling and e.p. information 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. --- diff --git a/backend.c b/backend.c index 7f8db9e..c4e9316 100755 --- 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= 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 --- 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= 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= 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= 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= 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); } }