picoEngine: Fixing FEN + Moves!

fenplusmoves

Today I was able to finally put the nail in the coffin of the FEN + Moves bug in picoEngine! It felt great to close that long standing issue. You can even check out the commit for all the details, but as usual, I’ll talk about the pertinent part here.

The reason this is important is because many chess programs allow you to set up a position on the board, and then seek the engine’s advice on a next best move. Initially, while meeting the UCI (Universal Chess Interface) standard, I enabled picoEngine to accept either “movepos” ( a move by move insertion from the program to my chess engine ), or “FEN” ( a string of numbers and letters that represents the current board ). What I didn’t realize is that some chess programs did not do what I expected per the UCI guidelines.

The way I understood it by reading the UCI guidelines, was that the controlling chess program (say Arena, in our case) would choose before hand to either send “movepos” with a list of moves to get the board set up, or it would send “FEN” with a string of the board setup for each move. I understood that if you set up the board in an unusual position, it would need to send FEN commands to my engine. That made sense.

What I thought would happen for further moves, however, did not. I thought, since it started as a FEN command game, then every turn, it would send the FEN string of the new board. Some chess programs do this. In the case of many programs, such as Arena, it did something quite unexpected to me. For further moves, it would send the FEN to set the board, then a string of the moves after that setup. So it was doing both movepos and FEN all at the same time!

Knowing that now was an easy fix. Simply read the FEN to get the current position, and if you have follow on moves, then apply the movepos rules on them. What gave me the biggest hiccup, however, was a slight miscalculation on my part. I was feeding the FEN into the engine in such a way that the board came out mirrored! Here was the code I used to fix it:

From this:

	int j = stringBoard.length();	
        for (int i = 0; i < j; i++) {
	if (i < 64){ m_theBoard[63 - i] = stringBoard.at(i); }
	}

To this:

 

        for (int i = 0; i < 8; i++) {
		m_theBoard[i+0] = stringBoard.at(i+56);
		m_theBoard[i+8] = stringBoard.at(i+48);
		m_theBoard[i+16] = stringBoard.at(i+40);
		m_theBoard[i+24] = stringBoard.at(i+32);
		m_theBoard[i+32] = stringBoard.at(i+24);
		m_theBoard[i+40] = stringBoard.at(i+16);
		m_theBoard[i+48] = stringBoard.at(i+8);
		m_theBoard[i+56] = stringBoard.at(i+0);
	}

The picoEngine is really coming along nicely! I think it is playable now, and I’m just about done working on it. It’s still not very bright yet, but it is getting better!

Linux – keep it simple.

picoEngine Meets FEN

print

One of the more interesting parts to programming chess engines, is using the UCI, Universal Chess Interface. In that interface standard are very specific settings. One of those is that engines should accept input as either move by move, or through FEN.

The FEN part was actually quite easy. Just breaking down characters of the line and figuring out what goes where. The toughest part was understanding vectors so I could do what I wanted to do. Here’s a glimps of the code:

vector<string> split(string str, char delimiter) {
vector<string> internal;
stringstream ss(str); // Turn the string into a stream.
string tok;

while(getline(ss, tok, delimiter)) {
internal.push_back(tok);
}

return internal;
}
………………………………………..Edited for space…………………………………
void inputPosition(string posString)
{
vector<string> sepVect = split(posString, ‘ ‘);
string str1 = sepVect[1];
if (sepVect[1] == “fen”)
{
// FEN board setup.
string stringBoard = “”;
string str2 = sepVect[2];
for (int i = 0; (unsigned)i < str2.length(); i++) {
char myChar = str2.at(i);
if (isdigit(myChar))
{ int imyChar = myChar – ‘0’;
for (int a = 0; a < imyChar; a++)
{ stringBoard = stringBoard + “-“; }
}
else if (isalpha(myChar))
{ stringBoard = stringBoard + myChar; }
} // end for.
int j = stringBoard.length();
for (int i = 0; i < j; i++) {
if (i < 64){ theBoard[i] = stringBoard.at(i); }
}
if (sepVect[3].at(0) == ‘w’)
{ whitesTurn = true; } else { whitesTurn = false; }
if (sepVect[4].at(0) == ‘K’)
{ Kcastle = true; } else { Kcastle = false; }
if (sepVect[4].at(1) == ‘Q’)
{ Qcastle = true; } else { Qcastle = false; }
if (sepVect[4].at(2) == ‘k’)
{ kcastle = true; } else { kcastle = false; }
if (sepVect[4].at(3) == ‘q’)
{ qcastle = true; } else { qcastle = false; }
if (sepVect[5].at(0) == ‘-‘)
{ enPassant = false;} else { enPassant = true;}
moveSince = stoi (sepVect[6]);
turnCount = stoi (sepVect[7]);
} // End FEN

I just broke down the string into vectors separated by spaces. Then in each vector, I figured out where the piece needed to go, or how many blank spaces I needed.

Now I still have to work out a few oddities, but I think this should work fairly well, and seems to have in the few test runs I’ve given it. You can check out the whole commit on my GitLab if you’d like!

Linux – keep it simple.

Blindfold Chess, Mr. picoEngine?

While building the picoEngine in C++, I will often be wondering what the engine is thinking. One of the problems is that I can not “see” the engine’s board, so I don’t know why it would make a particular move. So, I added a print function. This also is in keeping with my “engine mentor” Logic Crazy, who often used this technique so he could evaluate the board position.

The code is rather straight forward:

string printBoard = “”;

for (int i = 0; i < 64; i++){

printBoard = printBoard + theBoard[i];

}

cout << printBoard << ” ” << whitesTurn << ” ” << Kcastle

<< ” ” << Qcastle << ” ” << kcastle << ” ” << qcastle

<< ” ” << moveSince << ” ” << turnCount << endl;

Not only did it work, but it seems to be rather helpful. Now, as I work on inserting positions via FEN and the startpos moves system that is defined in the UCI, it makes checking my work easy. Here is a screen shot of it in action:

print_picoEngine

Linux – keep it simple.