It may come as a surprise to you, but I like chess. I am a member of my local chess club where I play occasionally. I am not very good at chess. I would call myself a beginner that knows all the rules. This will be the first in a series of posts (jinx) on chess. The main objective will be to implement a chess engine that I can not beat. Most of the information in these posts can be found in some way or another on https://www.chessprogramming.org/Main_Page.
Before we do anything we have to define the game of chess. This is like explaining chess to someone who has never played. A computer is not a person, so in order to explain chess to it we need to map them to structures in the programming language of our choice (C). Each chess concept will be explained with its accompanying structure.
I think the best place to start is the chessboard. Chess is played on an 8 by 8 grid. The rows are called ranks and the columns files. The ranks are given the number 1-8 and the files the letters a-h. A cell of the grid is called a square. By convention we name a square by its file first and then its rank. For example: e4, e5, f4. The squares on the chessboard also have a color, either black or white. The black and white pattern of the board is called checkerboard pattern, after another much played game. Remember that the a1 square is black.
What is the best computer representation for the chessboard? A grid screams to be represented as an array. We then should link indices with square names, such as a1 is equal to the 0 element of the array. Indices and more generally numbers, have arithmetic operations defined on them. We can add, subtract, multiply, etc. This could come in handy later.
We should take a step back (or up) to mathematics. What a board really is, is a function (or a map) from the domain of squares to the range of pieces. More formally: \[ b : S \to P \] where \(b\) is the board function, \(S\) is the set of chessboard squares, and \(P\) is the set of chess pieces.
Since we are working in C, we have access to native, beafy 64-bit, unsigned integers. These bad boys will fit all of our squares exactly. However, we can only encode ones or zeros on each square. We will store multiple ‘bitboards’ and an array of pieces.