Chess Bin

Computer Chess Information and Resources

Piece Square Table

Today I want to discuss the Piece Square Table

Originally the piece square tables were declared in a separate class that was used by the Evaluation function.  However I found that it is more efficient to save the extra method calls and perform the piece square table lookups directly in the evaluation function. 

Hence I have modified this post to simply describe the piece square table and the logic behind the numbers assigned to each position.

As I have already stated the piece square tables are used chess board Evaluation class to score points based on the current position of the chess piece.  The main idea behind this code is that certain positions for chess pieces are better than others.  Fox example it is better for knights to stay away from the edge of the board.  Pawns should control the center of the board and advance forward. 

I have decided not to create a piece square table for every single chess piece.  I have omitted Queens and Rooks.  I could not find good enough positional tactical advantages for Rooks and Queens to warrant the performance cost of a table lookup for each of their positions.

Here are the piece square tables used by my chess engine:

Pawns are encouraged to stay in the center and advance forward:


private static readonly short[] PawnTable = new short[]
{
     0,  0,  0,  0,  0,  0,  0,  0,
    50, 50, 50, 50, 50, 50, 50, 50,
    10, 10, 20, 30, 30, 20, 10, 10,
     5,  5, 10, 27, 27, 10,  5,  5,
     0,  0,  0, 25, 25,  0,  0,  0,
     5, -5,-10,  0,  0,-10, -5,  5,
     5, 10, 10,-25,-25, 10, 10,  5,
     0,  0,  0,  0,  0,  0,  0,  0
};

Knights are encouraged to control the center and stay away from edges to increase mobility:

private static readonly short[] KnightTable = new short[]
{
    -50,-40,-30,-30,-30,-30,-40,-50,
    -40,-20,  0,  0,  0,  0,-20,-40,
    -30,  0, 10, 15, 15, 10,  0,-30,
    -30,  5, 15, 20, 20, 15,  5,-30,
    -30,  0, 15, 20, 20, 15,  0,-30,
    -30,  5, 10, 15, 15, 10,  5,-30,
    -40,-20,  0,  5,  5,  0,-20,-40,
    -50,-40,-20,-30,-30,-20,-40,-50,
};

Bishops are also encouraged to control the center and stay away from edges and corners:


private static readonly short[] BishopTable = new short[]
{
    -20,-10,-10,-10,-10,-10,-10,-20,
    -10,  0,  0,  0,  0,  0,  0,-10,
    -10,  0,  5, 10, 10,  5,  0,-10,
    -10,  5,  5, 10, 10,  5,  5,-10,
    -10,  0, 10, 10, 10, 10,  0,-10,
    -10, 10, 10, 10, 10, 10, 10,-10,
    -10,  5,  0,  0,  0,  0,  5,-10,
    -20,-10,-40,-10,-10,-40,-10,-20,
};

Kings have 2 piece square tables, one for the end game and one for the middle game.  During the middle game kings are encouraged to stay in the corners, while in the end game kings are encouraged to move towards the center.

private static readonly short[] KingTable = new short[]
{
  -30, -40, -40, -50, -50, -40, -40, -30,
  -30, -40, -40, -50, -50, -40, -40, -30,
  -30, -40, -40, -50, -50, -40, -40, -30,
  -30, -40, -40, -50, -50, -40, -40, -30,
  -20, -30, -30, -40, -40, -30, -30, -20,
  -10, -20, -20, -20, -20, -20, -20, -10,
   20,  20,   0,   0,   0,   0,  20,  20,
   20,  30,  10,   0,   0,  10,  30,  20
};

private static readonly short[] KingTableEndGame = new short[]
{
    -50,-40,-30,-20,-20,-30,-40,-50,
    -30,-20,-10,  0,  0,-10,-20,-30,
    -30,-10, 20, 30, 30, 20,-10,-30,
    -30,-10, 30, 40, 40, 30,-10,-30,
    -30,-10, 30, 40, 40, 30,-10,-30,
    -30,-10, 20, 30, 30, 20,-10,-30,
    -30,-30,  0,  0,  0,  0,-30,-30,
    -50,-30,-30,-30,-30,-30,-30,-50
};

The above tables are used during the evaluation method to lookup the positional values to help calculate the chess board score.

Here is an example of how the above tables would be used to lookup a value for a white pawn position:

score += PawnTable[position];

And here is the code to perform the same lookup for a black pawn:

byte index = (byte)(((byte)(position + 56)) - (byte)((byte)(position / 8) * 16));

score += PawnTable[index];

If you want to download a C# Solution project that contains all of the above code plus a graphical user interface that will allow you to make valid moves on the board have a look my C# Chess Game Starter Kit.

Starting the chess engine

Bringing it all together, starting the chess engine.

This post will bring all of the previous sections together in the discussion of the chess engine class.  At this time I will assume that you have already read the previous sections related to Chess Board Square, Chess Board and Chess Piece Representation as well as the Chess Piece Moves and Chess Piece Valid Moves.  Today I will not provide a complete chess engine listing because we have not yet discussed move searching and Chess Board Evaluation.  However at the end of this section we will have a basic chess engine that can:

    1. Track chess piece locations on the chess board
    2. Provide a list of valid moves for each chess piece, including en passant and castling
    3. Track whose move it is.
    4. Track move history.
    5. Setup a starting chess board.

This in theory once we create a graphical user interface this skeleton chess engine would allow you to play a two human player chess game.

Chess Engine class is declared as public sealed


public sealed class Engine

Chess Engine class will contain 3 members that will represent the current chess board, previous chess board whose move it currently is.  Previous Chess Board will store the last chess board prior to the last move.  Please notice that the Previous Chess Board member will potentially give us easy undo functionality.


internal Board ChessBoard;
internal Board PreviousChessBoard;

public ChessPieceColor WhoseMove
{
    get { return ChessBoard.WhoseMove; }
    set { ChessBoard.WhoseMove = value; }
}

The constructor is a bit complicated as it performs the following actions:

    • Instantiate above members and set the initial move to White
    • Initiate Chess Piece Motion (Pre-calculate all possible moves for all pieces on all chess board squares possible)
    • Assign Chess pieces to the chess board in the starting position of a standard chess game.
    • Generate valid moves for the chess pieces in their current positions.

public Engine()
{
    ChessBoard = new Board();
    MoveHistory = new Stack<MoveContent>();

    RegisterStartingBoard();
    ChessBoard.WhoseMove = ChessPieceColor.White;   
   
    ChessPieceMoves.InitiateChessPieceMotion();
    PieceValidMoves.GenerateValidMoves(ChessBoard);
}

Notice the Constructor uses a method called Register Starting Board.  This method constructs all the chess pieces necessary for the starting chess board and registers them with the chess board object.

In the above code a helper method was used called Register Piece. This method assigns the created chess piece to the desired location on the chess board.


private void RegisterPiece(byte boardColumn, byte boardRow, ChessPiece Piece)
{
    byte position = (byte)(boardColumn + (boardRow * 8));    

    ChessBoard.Squares[position].Piece = Piece;

    return;
}

The remaining method that I will indroduce today is the MovePiece method.  This code will allow you to move chess pieces around the chess board.  The method will return true if the move was successful and false if the move was not valid.

public bool MovePiece(byte sourceColumn, byte sourceRow,
         byte destinationColumn, byte destinationRow)
{
 byte srcPosition = (byte)(sourceColumn + (sourceRow * 8));
 byte dstPosition = (byte)(destinationColumn + (destinationRow * 8));

 Piece Piece = ChessBoard.Squares[srcPosition].Piece;

 PreviousChessBoard = new Board(ChessBoard);
 
 Board.MovePiece(ChessBoard, srcPosition, dstPosition, PromoteToPieceType);

 PieceValidMoves.GenerateValidMoves(ChessBoard);
 
 //If there is a check in place, check if this is still true;
 if (Piece.PieceColor == ChessPieceColor.White)
 {
  if (ChessBoard.WhiteCheck)
  {
   //Invalid Move
   ChessBoard = new Board(PreviousChessBoard);
   PieceValidMoves.GenerateValidMoves(ChessBoard);
   return false;
  }
 }
 else if (Piece.PieceColor == ChessPieceColor.Black)
 {
  if (ChessBoard.BlackCheck)
  {
   //Invalid Move
   ChessBoard = new Board(PreviousChessBoard);
   PieceValidMoves.GenerateValidMoves(ChessBoard);
   return false;
  }
 }

 MoveHistory.Push(ChessBoard.LastMove);

 return true;
}

Generating a Starting Chess Position

At this point we it would be nice if we were able to add some chess pieces to our chess board.  Originally I wrote a method that would declare 32 chess pieces and assign them to the correct chess board square.  However eventually I wanted to implement FEN notation into my chess engine.  FEN notation is an easy way to describe chess board positions.  It is somewhat of a standard in computer chess circles.  Hence once I implemented a method that can read a FEN string and setup the chess board based on the FEN string values, I had an easy way to create my starting chess position. 


ChessBoard = new Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");

The full source code for the FEN methods can be found on the FEN page.

To summarize, our chess engine class contains the current chess board (Board ChessBoard) as well as a copy of the chess board as it looked prior to the last move (Board PreviousChessBoard).  The Chess Engine knows whose move it currently is (ChessPiece.ChessPieceColor WhoseMove).  The constructor of the Chess Engine creates all the chess pieces required for a standard chess game and registers them with the chess board using the Register Piece method.  The chess engine constructor will also Initiate Chess Piece Motion and Assign valid moves to each chess piece based on the pieces current position and the board layout.  Moving chess pieces around the board is handled by the MovePiece method.

If you want to download a C# Solution project that contains all of the above code plus a graphical user interface that will allow you to make valid moves on the board have a look my C# Chess Game Starter Kit.

Project Goals

Goal 1

Create a chess game that was capable of consistently winning games against me.

Status: Achieved as of August 18, 2008. 

Goal 2 

Defeat Chess Titans at level 10, the free Chess Game that comes with Windows Vista.

Status: Achieved as of November 7th, 2009 although not consistently

Goal 3 

Interface with WinBoard, the open source chess board.  This is necessary to submit my Chess Engine to most Computer Chess tournaments. 

Status: Achieved as of December 18th 2009: Download Link

Goal 4 

Enter a computer chess tournament and beat someone’s chess engine. 

Status: Acheived as of April 5th 2010, Entered WBEC Ridderkerk's 18th Edition Tournament and beat more than one chess engine.


Goal 5 

Defeat Little Chess Partner , the free Java Chess Game from the nice people at Lokasoft.

Status: October 28th 2008, tied based on three move repetition

Goal 5 

Create an Online Interface for ChessBin Chess

Status: January 14th 2009, created an online interface using Microsoft Silverlight

Additional Goals will be added from time to time or as older Goals are completed.