FEN parsing issue
FEN parsing issue
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.
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.
-
- Posts: 616
- Joined: Thu May 19, 2011 1:35 am
Re: FEN parsing issue
Probably undefined behavior.
Turn your compiler warnings to maximum. Look for things like "Unitialized variable" in the output.
Turn your compiler warnings to maximum. Look for things like "Unitialized variable" in the output.
-
- Posts: 616
- Joined: Thu May 19, 2011 1:35 am
Re: FEN parsing issue
Did you find your problem?
Re: FEN parsing issue
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.
-
- Posts: 616
- Joined: Thu May 19, 2011 1:35 am
Re: FEN parsing issue
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.
If you don't want to expose your code, that is fine too.
Re: FEN parsing issue
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:
Then it works fine! But as far as I can tell, this loop does absolutely nothing.
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++) {
}
- Attachments
-
- Fen.cpp
- (2.13 KiB) Downloaded 264 times
-
- Posts: 616
- Joined: Thu May 19, 2011 1:35 am
Re: FEN parsing issue
I analyzed this:
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.
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 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
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:
To this:
And it worked.
Code: Select all
n = atoi(&temp); // Where temp is the current character being looked at
Code: Select all
char numString[] = {temp, '\0'};
n = atoi(numString);
-
- Posts: 616
- Joined: Thu May 19, 2011 1:35 am
Re: FEN parsing issue
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?
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?
-
- Posts: 40
- Joined: Sat Jun 19, 2010 11:00 pm
- Real Name: Lee Neuse
Re: FEN parsing issue
If you are only parsing a single digit -- such as in FEN parsing -- a simple trick is to compute the result:
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
,,,^..^,,,
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!
Cheers!
Humble Programmer
,,,^..^,,,