Page 1 of 1

FEN parsing issue

Posted: Sun Feb 03, 2013 11:33 pm
by CDaley11
I've lately noticed a strange problem in my FEN parsing function. For example, if I give my engine the following command:
position fen rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
This is the starting position with white's first move being e2e4. After parsing the fen my program prints out a text based board to show what the board currently looks like. If I run my program from within the debugger in Xcode, it gets the board position correct, every time. But if I instead launch the executable myself and run it from within terminal, it doesn't get the position right and it is all messed up. But it only messes up around half the time! This is bothering me, it simply doesn't make sense for a program to mess up only half of the time. And here's another strange part: I added in a line of code that spits back out the fen string token , just to make sure it was getting the token right in both cases. In both cases it was getting the token right. But with printing out the fen string before parsing it, the program never messes up, in either xcode or terminal. But if I simply make it so that my program does not print out the fen string before parsing it, then it will mess up half of the time while running in terminal. I've tried this dozens of times, it really is very strange.

Re: FEN parsing issue

Posted: Mon Feb 04, 2013 3:32 pm
by User923005
Probably undefined behavior.
Turn your compiler warnings to maximum. Look for things like "Unitialized variable" in the output.

Re: FEN parsing issue

Posted: Tue Feb 05, 2013 7:07 pm
by User923005
Did you find your problem?

Re: FEN parsing issue

Posted: Wed Feb 06, 2013 8:44 pm
by CDaley11
No, unfortunately i didn't :(. I've spent quite a while fiddling with it and I just cannot seem to get it to work right. It works fine in the debugger in Xcode but it simply wont work when I run it in terminal or with a gui. It really is very strange. I'll keep working on it though and ill post if I can get it to function right.

Re: FEN parsing issue

Posted: Wed Feb 06, 2013 8:56 pm
by User923005
If you post your source code, someone can probably figure it out for you.
If you don't want to expose your code, that is fine too.

Re: FEN parsing issue

Posted: Thu Feb 07, 2013 3:56 am
by CDaley11
This is my Fen parsing code. In case you're wondering, board is a struct.

EDIT: One really weird thing I noticed, if I add this code right before the parsing loop:

Code: Select all

for (int a=0;a<0;a++) {

}
Then it works fine! But as far as I can tell, this loop does absolutely nothing.

Re: FEN parsing issue

Posted: Thu Feb 07, 2013 8:45 pm
by User923005
I analyzed this:

Code: Select all

#include <ctype.h>
#include <string.h>
#include <stdlib.h>

#define BLACK 0
#define WHITE 1

typedef struct board_type {
    int turn;
    int enPassantSquare;
    int castling[2][2];
    int movesSincePawnPushOrCapture;
    int totalFullMoves;
} board_type;

board_type b;

board_type *board = &b;

char *getToken(char *, char *);
void clearBoard(board_type *);
void setSquare(board_type *,  int , int , int);
int parseSquare(char *);

char *parseFen(char *ptr) { // The fen parsing function
    clearBoard(board);
    const char *pieceNames = "PRNBQKprnbqk";
    int rank = 7; // Rank and file iterator
    int file = 0;
    char *token = new char[80];

    ptr = getToken(ptr, token);  // Get the first token in the string, which should be the piece positions
    while (rank >= 0) {
        if (*token == '/')
            token++;
        char temp = *token;
        int n = 0;
        if ((n = atoi(&temp))) {
            file += n;
            if (file >= 8) {
                file = 0;
                rank--;
            }
            token++;
            continue;
        }
        for (int a=0; a < 2; a++) {
            for (int b=0; b < 6; b++) {
                if (temp == pieceNames[a * 6 + b]) {
                    // Sets a specific square on the board to a specific piece type and color. b = color, a = piece type
                    setSquare(board, b, a, rank * 8 + file);
                    break;
                }
            }
        }
        file++;
        if (file >= 8) {
            file = 0;
            rank--;
        }
        token++;
    }
    ptr = getToken(ptr, token);
    if (*token == 'w')
        board->turn = WHITE;
    else
        board->turn = BLACK;
    ptr = getToken(ptr, token);
    for (int a=0; a < strlen(token); a++) {
        if (token[a] == 'Q')
            board->castling[WHITE][0] = true;
        else if (token[a] == 'K')
            board->castling[WHITE][1] = true;
        else if (token[a] == 'q')
            board->castling[BLACK][0] = true;
        else if (token[a] == 'k')
            board->castling[BLACK][1] = true;
    }
    ptr = getToken(ptr, token);
    if (*token != '-') {
        char square[2] = {token[0], token[1]};
        int sq = parseSquare(square);
        board->enPassantSquare = 1ULL << sq;
    }
    ptr = getToken(ptr, token);
    board->movesSincePawnPushOrCapture = atoi(token);
    ptr = getToken(ptr, token);
    board->totalFullMoves = atoi(token);
    return ptr;
}
I don't see anything obviously obnoxious in there.
I suspect that the fault is in one of these routines:
char *getToken(char *, char *);
void clearBoard(board_type *);
void setSquare(board_type *, int , int , int);
int parseSquare(char *);

It will be much easier to help you if you attach code in a state that actually compiles.

Re: FEN parsing issue

Posted: Sun Feb 10, 2013 12:36 am
by CDaley11
I finally figured out the problem! When I give it the FEN rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1 Then for some reason when I run the program in the debugger it interprets the 1 (in bold) just fine, but when running in terminal it interprets it as a 10! This is using the basic atoi(const char *) function. I changed this code:

Code: Select all

n = atoi(&temp); // Where temp is the current character being looked at
To this:

Code: Select all

char numString[] = {temp, '\0'};
n = atoi(numString);
And it worked.

Re: FEN parsing issue

Posted: Sun Feb 10, 2013 12:43 am
by User923005
The atoi function assumes that a zero terminated string is supplied.
Now, since the next character is the letter P, conversion should stop.
So a return of 10 seems quite strange to me.
What compiler are you using?

Re: FEN parsing issue

Posted: Sun Feb 10, 2013 1:43 pm
by HumbleProgrammer
If you are only parsing a single digit -- such as in FEN parsing -- a simple trick is to compute the result:

Code: Select all

char[] temp = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1";
int iSkip = (int)(temp[18] - '0'); // subtract character for zero, NOT zero value!
This will convert the single digits '0' through '9' to their integer equivalents [0..9]. It obviously does not work on negative numbers, or numbers greater than 9.

Cheers!
Humble Programmer
,,,^..^,,,