Andy's LEGO® Mindstorms® Page
About this site
  
What's New?
  
Standard Disclaimer
Quite C
  
Francesco Ferrara
  
Getting Started
  
Installing Quite C
  
Compiling a project
  
Sample Code
Chess
  
The Robot Chess Project
  
Programming Chess
  
First Attempt
  
Version 0
  
Version 1
  
The Program
  
The State of Play
  
The User Interface
  
The Move Generator
  
The Move Applier
  
The Rating Algorithm
  
The Search Algorithm
  
Putting it all together
  
The Robot
  
The Head
  
Moving the head
  
Movies
  
Downloads: Source Executables, MLCad Models
4-in-a-Robot
  
4-in-a-Robot - the Robot
  
The 4-in-a-Robot Base
  
The 4-in-a-Robot Delivery Mechanism
  
The 4-in-a-Robot Controller
  
4-in-a-Robot - the Code
  
The 4-in-a-Robot Algorithm
  
The 4-in-a-Robot Control Programming
  
The 4-in-a-Robot Robot-less version
  
Installing 4-in-a-robot
  
Playing the robotless 4-in-a-robot
  
View the source code
Speech
  
The problems with speech
  
Sounds familiar
  
H8 Timers Background
  
Trial and Error
  
Volume Zapper
  
Actually Speaking
  
Speak.c - the code
  
The VB code generator
Some ideas for the future
  
Room positioning robot
  
Neural Net Bot
  
Pianola
  
Text to speech
LEGO® Mindstorms® Links

[268743]

The State of Play

 

State of play


The state of a game of chess can be broken down into the following data structures:

  • The Board: where each piece is on the board and what colour it is

  • The Current Go: who's turn it is to play

  • The Castle State: once a rook or king has moved, it cannot take part in castling, even if it moves back. The avaialble castle moves need to be stored

  • The Enpassant Square: When a pawn advances two squares on its first move, it can be taken by an enemy pawn moving to the place it would have occupied had it only moved one square, but only on the next move. This square is stored as the enpassant square

  • The 50 move draw: if no pawn has moved, no piece taken, and no check has occurred for 50 complete moves (ie 100 turns), then the game is drawn. We need to store a counter of how many moves like this have occurred so far.

  • The History: if the same position is reached three times within the course of a game, a draw occurs. Rather than store each state, it's more compact to store a history of each move.


Implementation of the state of play


The board


The board is represented by two arrays of 100 elements. Why? Let me explain my decision:
100 elements - one of the most time consuming processes in a chess program is generating moves. Most of the moves involve 'sliding' pieces around the board. By adding two extra rank/files to the board, we can mark these squares as 'off the board'. This simplifies generating moves for sliding pieces as one doesn't need to keep testing to see if the current square is off the board at the top/bottom/left/right, you just test to see if the current square is marked as 'off the board'
Two arrays - one for the colour of each square: black, white or empty; and one for the piece on each square: King, Queen, Rook, Knight, Bishop, Pawn, empty. This simplifies certain parts of the program as you often need to test the colour of a square but not the piece, and vice versa.

The current go


Rather easy this one, I just store black or white. I also have an overall state variable, setting it to checkmate black/white, draw, quit, and playing as appropriate. This makes the 'main loop' of the program quite simple:

While state is playing
if go is computer
make computer move
else
make player move

check we're still playing

The castle state


I use a couple of simple bitmask variables for the black and white castling state. Each has three flags, castle left, castle right, and castle done. As moves are applied we update these flags.
We also use the castling flags in the rating algorithm to give a point bonus for successful castling, and a penalty if castling is not available.

The en-passant square


Because the board is a 10x10 grid, we can use simple decimal notation for squares, e.g. 11 is A8 and 88 is H1. Note the board is numbered from top left to bottom right, which is a bit different to normal chess notation. Oh, we're talking about the en-passant square? Well, I store it if a pawn moves two spaces, and clear it to 0 otherwise.

The 50 move draw


Again this is pretty trivial, I store a count of the number of 'bland' moves, and increase it, or reset it to zero when a move is applied. Note that a draw occurs when the counter reaches 100, as in chess a move is two plays, one for each player.

The history


This is slightly more complicated. Rather than just storing each move, we need to also keep track of the castling flags, the enpassant square and the draw50 counter, so that we can use the history to undo moves from the board.
There's a neat little trick for quickly working out the three repetition draw in the code, based on the one in Tom's Simple Chess Program.
Unfortunately on the RCX we've only got limited memory, so the history is maintained only for the last 30 plays.

All the state variables and constants are declared in globals.h
You'll see that there an extra bit of state I maintain to speed up various processes - the king positions, this speeds up check testing.


Show Topic: The Program

Next Page: The User Interface