PGN Chess, a PHP Chess Board Representation for PHP Chess Engines

I am happy to share with you that I’ve recently written a chess board representation in PHP named PGN Chess which is freely available on GitHub under the GPL license, and today I’ll be explaining a couple of challenges that I came up with while implementing it. Let me start by saying what PGN Chess is.

This library can understand chess rules. PGN Chess represents games internally in the computer’s memory, which means it is somewhat of a building block serving as a basis for chess engines in order to analyze and make chess moves programmatically — for further information about how to use it please look at the README file on GitHub.

Games are instantiated this way:

As you see, it is all about instantiating a game and playing PGN moves. The call to the $board->play method returns true or false depending on whether or not a chess move can be run on the board. All action takes place in the $game object.

The API’s Interface Is Simple

isCheck()

Finds out if the game is in check.

isMate()

Finds out if the game is over.

status()

Gets the current game’s status.

piece()

Gets a piece by its position on the board.

pieces()

Gets the pieces on the board by color.

history()

Gets the game’s history.

captures()

Gets the pieces captured by both players.

About Chess Programming Challenges

OK, now I will tell you about some challenges of writing a chess board representation in PHP, and at this point I would recommend you take a look at PGN Chess’s Board class which is an extension of SplObjectStorage. The main idea is adding/removing object-oriented pieces to it as long as players make their moves on the board.

1. A Debugging Plan to the Rescue!

Challenge number one is: writing a chess board is much more trickier than it looks at first, especially because it requires a lot of time-consuming debugging.

The thing is that I ended up implementing a debugging plan that consisted in testing dozens and dozens of different PGN games of all times, from world champions’ games to common chess openings. This is why I created this example folder containing so many PGN files.

Bear in mind that apart from unit testing and debugging every single of them with the help of PHPUnit and Xdebug, you also need to visualize the games with a PGN viewer.

It is basically all about visualizing a sample PGN game at the same time that you Xdebug it making sure that the board’s variables – the current player’s turn, the squares being controlled by both players, the kings’ castling status, and so on — are consistent in every single step.

2. Figuring out Whether or Not the Board Is in Check

This is challenge number two. To my understanding, there is a special method in particular which is perhaps one of the most crucial on implementing a chess board: it is necessary to know at any time whether or not a chess move leaves the board in check!

Future chess moves must be simulated somehow, and as it often happens when it comes to solving problems this one in particular can be solved in several different ways. Here is my solution to the challenge.

I opted to rely on a do-undo-moves-based strategy, which works perfectly fine.

However, at a certain point while writing PGN Chess I thought: why not simulate moves on a cloned board? But PHP deep clones are quite tricky since it is completely up to you to implement them through PHP’s __clone magic method in a similar way as shown below.

And this possibility was dismissed because I didn’t feel comfortable cloning the entire Board object because that seemed to be a whole new problem in itself.

3. The Checkmate Algorithm

Finally, this is challenge number three. Here is how the checkmate algorithm is implemented in PGN Chess’s Board class.

Sure, I know there must be several ways to approach these problems but that is how I personally solved them. I hope you learned something helpful and enjoyed today’s post. This is all for now.

0 comentarios

¿Me dejas un comentario? ¡Gracias!

Deja un comentario

Los campos obligatorios están marcados con *