Dec 18, 2006

[Programming] FEN input/output methods

Peeking into the board class: To start off I created a bit of code which displays what the Board-class holds at the moment. This is a way of making sure we actually get the right numbers when using the FEN codes later on.

If you decided to skip writing any FEN code, you could use this piece of code forever. Trust me though, FEN-notation is a good thing. :)

It looks like this:

int i = 112;

while(i >= 0)
if((i & 0x88) == 0)
System.out.print(boardArray[i] + " ");
i -= 24;

And the output from a board with the starting position would be:

-3 -5 -4 -2 -1 -4 -5 -3
-6 -6 -6 -6 -6 -6 -6 -6
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
6 6 6 6 6 6 6 6
3 5 4 2 1 4 5 3
As you might've gathered from my Definitions file, negative numbers stand for black pieces, and king = 1, queen = 2, etc. And 0 for empty squares.

The reason I'm showing this is to illustrate one of the nifty features of the 0x88 setup. We want to view the board with the black pieces on top, so we start writing from the 'h8' square (index 112 in the array).

First we check if the square is on the board with i & 0x88, I went through this in an earlier post.

Now if the square is not on the board, we know we reached the edge, so we need to move to the next rank (the 7th rank since we're moving from the top). To get to the first square on the next rank all we have to do is subtract 24 from our current position. This works for any square that's one step off the board (120, 104, 88 etc.), and with this setup that's where we'll be when we want to change rank.

As a sidenote; adding 16 takes us one rank up, subtracting 17 takes us one square down diagonally to the left, and so on. This will be extremely useful when we start generating moves.

Ok, now we have a way of peeking at our board class.

FEN input/output: This is the first "programming" post I write, and even though I'd really like to bore you with the ins and outs of the code, it's really nothing special.

The output goes through all the properties of the class and creates a string accordingly.

The input goes through the inputted string character by character and inputs the information at the right place.

It's all quite basic, but there's one passage I'd like to show, the en passant passage in the inputFEN()-method. It looks like this:
case 3: // En passant
if(currentChar.equals("-")) enPassant = -1;
switch(currentChar.charAt(0)) // Find the row
case 'a': enPassant = 0; break;
case 'b': enPassant = 1; break;
case 'c': enPassant = 2; break;
case 'd': enPassant = 3; break;
case 'e': enPassant = 4; break;
case 'f': enPassant = 5; break;
case 'g': enPassant = 6; break;
case 'h': enPassant = 7; break;

// Get the next character (the rank)
currentChar = trimmedFen.substring(i,i+1);

// On rank 3 or else rank 6
if(currentChar.equals("3")) enPassant += 32; // Add 2 ranks to index
else enPassant += 80; // Add 5 ranks to index
First if the character is '-' there's no en passant. Now we look at the first part of the square, the row (a,b,c,...), we translate this to the index of the first rank. Then we go on to checking the rank, if it's the 3rd rank, all we have to do is add 32 to the number and we've moved up two ranks and get the right index. Same with rank six (the only other option since en passants only occur on the 3rd and 6th rank), now we add 80 and we've moved up 5 ranks.

Easy ey? :) Of course it's very possible to just take the coordinates and transform them into an index (using a transformation table, or some method), but this is faster and easier. And fast is what we need for move generation later on! As I keep saying. :)

Error handling: For now I have done very little to handle errors that might occur. Later on a thorough check to see if the inputted FEN-string is valid should be implemented. As it stands a faulty FEN-string could result in a crash. But as long as we're the ones inputting the strings, we should be ok, and if a crash occurs we know where it came from, just make sure we have valid strings in the first place.

Conclusion: Now we have an easy way of inputting positions into the engine, and also looking at the positions that arise on our virtual board.

Since this part of the code was so basic I didn't feel the need to go any deeper. If you want to see what I've done, take a look at the code (mediocre(dl2)). I've made sure to add a bunch of comments just about everywhere, so it should be easy to follow.

In later programming posts I'll be more thorough if needed, atleast on the not so obvious parts.

Next up is making and (hopefully, if I get it figured out) unmaking moves on the board, and after that comes the huge move generating project.

No comments: