A bitboard is a data structure commonly used in computer systems that play boardgames.
Bitboards are interesting because they allow the computer to answer some questions about game state with one logical operation. For example, if a chess program wants to know if the white player has any pawns in the center of the board (center four squares) it can just compare a bitboard for the player's pawns with one for the center of the board using a logical AND operation. If there are no center pawns then the result will be zero.
Query results can also be represented using bitboards. For example, the query "What are the squares between X and Y?" can be represented as a bitboard. These query results are generally pre-calculated, so that a program can simply retrieve a query result with one memory load.
However, as a result of the massive compression and encoding, bitboard programs are not easy for software developers to either write or debug.
For the more complicated game of chess, it appears the method was independently rediscovered later by the Kaissa team in the Soviet Union in the late 1960s, although not publicly documented, and again by the authors of the U.S. Northwestern University program "Chess" in the early 1970s, and documented in 1977 in "Chess Skill in Man and Machine".
A bitboard is a format that stuffs a whole group of related boolean variables into the same integer, typically representing positions on a board game. Each bit is a position, and when the bit is positive, a property of that position is true. In chess, for example, there would be a bitboard for black knights. There would be 64-bits where each bit represents a chess square. Another bitboard might be a constant representing the center four squares of the board. By comparing the two numbers with a bitwise logical AND instruction, we get a third bitboard which represents the black knights on the center four squares, if any.
At some point in any hardware and software system, the CPU must do the actual work. The idea behind the bitboard is to put software representations in a very CPU friendly format. In typical programming, a lot of information or memory bandwidth is wasted. For example, a chess program might want to know what number turn it is. The programmer assigned a variable to track the turn number. If she is using a 32-bit computer, she is able to track chess games up to billions of moves long. However, real chess games are almost always less than 200 moves and would only require a few bits to represent their turn numbers. The programmer has "wasted" a number of bits in the 32-bit number. She could easily have gotten by with only 16-bits or even 8-bits. Let's say the programmer wants to save memory. She could take some of those 32-bits and use them to track other information. Can white still castle? She can use the 17th bit to answer this yes or no question.
The programmer is now using one variable as two. This is not what she learned in her Computer Science 101 class. What has she gained? Well actually, nothing at all. She got to save four bytes; however, she had to write code to decode her special double variable into separate ones and back which took a lot more than four bytes. This is why typical languages are designed to "waste" bits in the first place--the cure is worse than the disease.
One thing she did gain is that some operations are faster. If she wants to know if it is turn forty and white has castled, she can answer this in one comparison rather than two.
Furthermore, modern CPUs have instruction pipelines that queue instructions for execution. A processor with multiple execution units can perform more than one instruction per cycle if more than one instruction is available in the pipeline. Branching (the use of conditionals like if) makes it harder for the processor to fill its pineline(s) because the CPU can't tell what it needs to do in advance. Too much branching makes the pipline less efective and potentially reduces the number of instructions the processor can execute per cycle. Many bitboard operations require fewer conditionals and therefore increase pipelining and make effective use of multiple execution units on many CPUs.
CPU have a bit width which they are designed toward and can carry out bitwise operation in one cycle in this width. So, on a 64-bit or more CPU, 64-bit operations can occur in one instruction. There may be support for higher or lower width instructions. Many 32-bit CPUs may have some 64-bit instructions and those may take more than one cycle or otherwise be handicapped compared to their 32-bit instructions.
If the bitboard must be larger than the width of the instruction set a performance hit will be the result. So a program using 64-bit bitboards would run faster on a real 64-bit processor than on a 32-bit processor.
Since the whole idea of bitboards is to do extreme optimization, bitboard engines may avoid function calls. A possible solution is to use tools that will inline function calls.
Most engines are written in fully compiled languages. C is a popular choice.
The theoretically fastest language would be one that is fully compiled and has direct support for useful bitwise instructions on the hardware platform it is implemented on. One possibility is a C compiler that supports assembly language extensions.
There are twelve types of pieces, and each type gets its own bitboard. Black pawns get a board, white pawns, etc. Together these twelve boards can represent a position. Some trivial information also needs to be tracked elsewhere; the programmer may use boolean variables for whether each side is in check, can castle, etc.
Constants are likely available, such as WHITE_SQUARES, BLACK_SQUARES, FILE_A, RANK_4 etc. More interesting ones might include CENTER, CORNERS, CASTLE_SQUARES, etc.
Examples of variables would be WHITE_ATTACKING, ATTACKED_BY_PAWN, WHITE_PASSED_PAWN, etc.
These bitboards rotate the bitboard positions by 90 degrees, 45 degrees, and/or 315 degrees. A typical bitboard will have one byte per rank of the chess board. With this bitboard it's easy to determine rook attacks across a rank, using a table indexed by the occupied square and the occupied positions in the rank (because rook attacks stop at the first occupied square). By rotating the bitboard 90 degrees, rook attacks across a file can be examined the same way. Adding bitboards rotated 45 degrees and 315 degrees produces bitboards in which the diagonals are easy to examine. The queen can be examined by combining rook and bishop attacks. Rotated bitboards appear to have been developed separately and (essentially) simultaneously by the developers of the DarkThought and Crafty programs. The Rotated bitboard is hard to understand if one doesn't have a firm grasp of normal bitboards and why they work. Rotated bitboards should be viewed as a clever but advanced optimization.
Artificial intelligence | Computer board games | Data structures | Computer chess
This article is licensed under the GNU Free Documentation License.
It uses material from the
"Bitboard".
Home Page • arts • business • computers • games • health • hospitals • home • kids & teens • news • physicians • recreation• reference • regional • science • shopping • society • sports • world