development of a chess engine
TRANSCRIPT
![Page 1: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/1.jpg)
Registration number 4692306
2015
Development of a Chess Engine
Supervised by Dr Gavin Cawley
University of East Anglia
Faculty of Science
School of Computing Sciences
![Page 2: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/2.jpg)
Abstract
The majority of chess engines are designed to play the most popular version of chess,
Western chess. While these engines can technically play several variants, there is rarely
any specific tactical implementations to adapt them to playing with more obscure rule-
sets and consequently the ability of said engines can be diminished. The purpose of
the project is to explore and examine the core components of a chess engine in order
to create an engine that specialises in a relatively unknown chess variant called Horde
Chess. Data is collected by testing different adaptations of the pieces used by Horde
chess and several specific tactical improvements. The analysis of the collected data
produce a set of interesting results and possible improvements to the original board set-
up. A final analysis on the efficiency of the engine is performed leading to improvements
to engine performance.
Acknowledgements
I would firstly like to thank my project supervisor, Dr Gavin Cawley, for his support and
feedback through the duration of this project. I would also like to acknowledge both
Dr. Pierre Chardaire and Dr. Richard Harvey for the support and organisation of the
module.
![Page 3: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/3.jpg)
CMPC3P2Y
Contents
1. Introduction 6
1.1. Selecting a Chess Variant . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Horde Chess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2. Principles of a Chess Engine 10
2.1. Board Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.1. Piece Centric . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.2. Square Centric . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2. Search Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.1. Shannon’s Types . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.2. Minimax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.3. Alpha-Beta Pruning . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.4. Further Optimisation . . . . . . . . . . . . . . . . . . . . . . . 13
2.3. Evaluation Philosophies . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.1. Performance Balance . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.2. Game Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.3. Shannon’s Evaluation . . . . . . . . . . . . . . . . . . . . . . . 15
3. Analysis of Horde Chess Strategy 16
3.1. White Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2. Black Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4. Engine Development 18
4.1. Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2. Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.3. Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.4. Graphical User Interface . . . . . . . . . . . . . . . . . . . . . . . . . 22
5. Evaluating Chess Engine Performace 23
5.1. Build Optimisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.2. Code Optimisations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Reg: 4692306 iii
![Page 4: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/4.jpg)
CMPC3P2Y
5.3. Transposition Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6. Evaluating Horde Chess Equality 26
6.1. Original Board Set-Up . . . . . . . . . . . . . . . . . . . . . . . . . . 26
6.2. Board Adaptations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6.2.1. No Extra Pawns . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6.2.2. Two Extra Pawns . . . . . . . . . . . . . . . . . . . . . . . . . 28
6.2.3. White Pawn Handicap . . . . . . . . . . . . . . . . . . . . . . 30
7. Conclusions 31
References 34
A. Minimax Algorithm Pseudocode 35
B. Alpha-Beta Pruning Algorithm Pseudocode 36
C. Claude Shannon’s Evaluation Function 37
Reg: 4692306 iv
![Page 5: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/5.jpg)
CMPC3P2Y
List of Figures
1. Dusany’s chess initial board set-up. . . . . . . . . . . . . . . . . . . . 7
2. A shortlist of chess variants to be considered for the engine. . . . . . . 8
3. Horde chess initial board set-up. . . . . . . . . . . . . . . . . . . . . . 9
4. Diagram illustrating how bitboards can represent a chessboard. . . . . 11
5. A graph showing the relation between depth and the number of moves
in the search tree. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6. The default board structure for horde chess as declared in the initialisa-
tion text file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7. Calculating the evaluation score . . . . . . . . . . . . . . . . . . . . . 21
8. Final Graphical User Interface . . . . . . . . . . . . . . . . . . . . . . 23
9. Visual Studio 2013 Ultimate Build Settings . . . . . . . . . . . . . . . 25
10. Alternative board arrangement with no extra pawns . . . . . . . . . . . 28
11. Alternative board arrangement with two extra pawns . . . . . . . . . . 29
12. Alternative board arrangement with a white pawn handicap . . . . . . . 30
13. Close-up to show moves and times at a depth of 5 . . . . . . . . . . . . 32
Reg: 4692306 5
![Page 6: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/6.jpg)
CMPC3P2Y
1. Introduction
The objective of this project is to create a chess engine that can play either the stan-
dard ‘Western’, or ‘International’, chess or an alternative variant of chess. Through
research, it is clear that the majority of chess engines specialise in the standard ver-
sion of chess; however, there are many that play other variations such as ‘Xiangqi’ and
‘Shogi’ (commonly referred to as ‘Chinese Chess’ and ‘Japanese Chess’ respectively).
While deciding to pursue the more frequently used and most familiar version of chess
may be preferable due to the volume of literature available on the strategies used, this
decreases potential for experimentation and originality in the more advanced strategic
decisions that the engine makes. For these reasons, the more interesting and informative
way to approach this is to choose a variant of chess that is not as common and thus will
offer greater opportunities to research and study different strategic decisions.
1.1. Selecting a Chess Variant
There are several ways that Western chess can be adapted to create a variant. Often the
variant will use a larger or smaller chessboard than Western chess’ 8x8 tile board, for
example Shogi chess utilises a 9x9 board with 81 individual tiles. In some cases the
geometry of each tile is changed to create boards that differ from the standard square.
Glinski’s Hexagonal Chess uses 91 hexagonal tiles, or hexes, comprised of 3 different
colours that create a hexagonal board where each edge is 6 hexes long.
The standard board set-up can be adapted to create alternative variances by adding or
removing pieces that belong to the standard piece set. This creates a completely different
strategic outlook without editing the board array. Generally, these variants also change
the game objective and the conditions that need to be met for either team to win or a
stalemate to be declared. Figure 1 shows the starting board used in Dusany’s chess, a
good example of a variant that has these properties by adapting one of the piece-sets to
contain purely pawns. A more extreme approach is editing the piece set itself by adding
new unorthodox pieces with different properties. These new pieces are known as ‘fairy
pieces’ and are their properties have no limits. Examples of fairy pieces include the
‘Princess’, an amalgamation of a knight and a bishop that can move in the fashion of a
Reg: 4692306 6
![Page 7: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/7.jpg)
CMPC3P2Y
Image generated at http://www.jinchess.com/chessboard/composer/
Figure 1: Dusany’s chess initial board set-up.
bishop or a knight. This is exceptionally useful as it means that a princess piece, unlike
a regular bishop, is not restricted to the colour tile that it started on. Another is the
‘Nightrider’ piece, which is displayed as an inverted knight. The nightrider moves like
a knight but can make any number of knight moves in any one direction, so long as none
of them are blocked.
Due to the complexity of traversing a board that uses tiles of a different shape, these
variants should be disregarded while choosing the correct chess variant. Instead, a vari-
ant that either uses fairy pieces or that adapts the standard board set-up with simple
game objective changes should be the main focus when making a selection. Using these
criteria, a shortlist of variants that are suitable for the engine is created and shown in
Figure 2.
Using the shortlist described in Figure 2, a decision needs to be made on which of
the three variants is the most suitable by briefly analysing the scope for experimentation
and the frequency of use in chess engines. Following these principles, it suggests that
the best choice for the project is Horde chess as there is a relatively small amount of
research performed on this variant when compared to the others.
Reg: 4692306 7
![Page 8: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/8.jpg)
CMPC3P2Y
King’s Corner Chess
The king is placed in the bottom right corner and the rest of the bottom row is
arranged randomly. Each side uses the same random set-up and each of side
must have one bishop on white and one on black. The pieces do not mirror the
opposition in the same way as Western chess.
Horde Chess
The white side is set up in the same way as Western chess and the black side is
comprised of 32 pawns. The black side wins in the standard Western fashion of
checkmating the white king, white wins if all the black pawns are taken and a
stalemate is declared if either side has no valid moves.
Knightmate Chess
Very similar to Western chess, except the knight swap roles with the king. Ef-
fectively this means that each player has two kings and one knight and the player
must attempt to capture, or ‘knightmate’, the opposition knight. The pieces keep
their original movement characteristics and pawns can promote to kings instead
of knights.
Figure 2: A shortlist of chess variants to be considered for the engine.
1.2. Horde Chess
Horde chess is a variation of a more well recognised variation called Dusany’s chess,
in which one side has the standard set-up and the opposition’s ranks are composed of 4
rows of pawns.
The main difference with Horde chess is the placement of the pawns, with the two
central pawns that occupy the spaces where the king and queen would sit on a standard
chessboard set-up are moved to the fifth row, as shown in Figure 3. One of the most
important factors of horde chess is that the board set-up is still being refined, due to
the large weighting towards the white side, which can be seen in Table 1. This enables
the opportunity to examine a range of initial pawn structures in order to create a more
balanced game.
Reg: 4692306 8
![Page 9: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/9.jpg)
CMPC3P2Y
Image generated at http://www.jinchess.com/chessboard/composer/
Figure 3: Horde chess initial board set-up.
Table 1: Statistics of Horde Chess Resultsa
Winner Number of Wins Win Percentage
White 6351 71.56%
Black 2258 25.44%
Stalemate 266 2.99%
a Statistics collected by Brainking.com over 8875 matches
Furthermore, as Horde chess has not had a large quantity of strategic research per-
formed on the game type, it allows for a more innovative approach to the strategic
decisions that the engine will need to make to improve it’s ability. The variant differs
from Western chess enough to essentially render the majority of the common strategies
used redundant when it comes to Horde chess and provides a compelling challenge.
Reg: 4692306 9
![Page 10: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/10.jpg)
CMPC3P2Y
2. Principles of a Chess Engine
Upon analysing the game of chess and applying an understanding of software devel-
opment, you can break the game down into 3 core components: board representation,
search functions and move evaluation. For each of these elements there are a variety of
approaches that can be used, which will be outlined and assessed in this section.
2.1. Board Representation
As with any real-world problem that needs to be translated into a form that a computer
can understand, there are different philosophies to represent a chessboard in code. The
two key approaches to this issue are: a system that focuses on storing data for each of
the pieces on the board, piece centric, or a system that stores data for each tile on the
board, square centric.
2.1.1. Piece Centric
A piece centric representation stores information for each piece on the board including,
but not limited to, the location of the piece and colour. The most frequently used im-
plementation of this approach uses bitboards, a finite set of no more than 64 bits, where
each bit represents a certain piece of information about the subject; as illustrated in Fig-
ure 4. The main advantage to using bitboards is that many of the different analytical
techniques used in the search and evaluation stages can be performed a lot faster using
bitwise operations between two bitboards (Rasmussen, 2004). While bitboards defi-
nitely have performance advantages over a square centric approach, their readability is
far lower; thus the amount of bugs introduced during the implementation will be higher.
Because of the importance of having a bug free board representation to build the search
and evaluation on, this may not be the most suitable approach for the engine.
2.1.2. Square Centric
Unlike the piece centric approach, a square centric board representation focuses on em-
ulating the board itself by storing information on a tile by tile basis. A common data
structure used for this is an 8x8 array of integers for random access, which is more
Reg: 4692306 10
![Page 11: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/11.jpg)
CMPC3P2Y
Source : http://www.onjava.com/pub/a/onjava/2005/02/02/bitsets.html?page=2
Figure 4: Diagram illustrating how bitboards can represent a chessboard.
commonly represented as a one-dimensional array as opposed to a two-dimensional ar-
ray, where each integer represents a specific piece type and colour combination (Hyatt,
1999). This method allows the engine to traverse the board and check each element for
the value of the tile, which will indicate whether that square on the board contains a
specific piece or is an empty square. While this design can make the search and evalu-
ation functions less efficient, it vastly improves readability and will reduce the amount
of errors introduced when implementing the system.
2.2. Search Functions
In any chess engine, the search is the most important part of the system and needs to be
as efficient as possible. This is because the majority of the engine’s power stems from
the amount of moves into the future it can read, otherwise known as the depth or ply of
the search. The search function is going to look at every possible valid move for the side
to move and then for each of those moves check every move that can be made after; this
Reg: 4692306 11
![Page 12: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/12.jpg)
CMPC3P2Y
would be to a depth of 2. The aim of the chess engine is to be able to search to a depth
of 5 in a reasonable time but, as illustrated in Figure 5, the amount of individual board
evaluations approximately increases as an xn function where x is the number of possible
moves for depth 1 and n is the depth of the search.
Figure 5: A graph showing the relation between depth and the number of moves in the
search tree.
2.2.1. Shannon’s Types
Claude Shannon, one of the pioneers of computer chess, described two types of search:
Type A and Type B (Shannon, 1950). Type A searches, or brute-force searches, look
at every possible variation of the board to a given depth. Type B searches, or selective
searches, use heuristics to only look at branches of the search tree that are promising.
The brute-force searches that Shannon categorised will find the best move possible with
no errors, but will take longer than the Type B searches. Selective searches are much
faster than brute-force searches, but there is the possibility that the best move may be
Reg: 4692306 12
![Page 13: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/13.jpg)
CMPC3P2Y
discarded for a slightly worse move. These Type B searches were preferred in the earlier
years of chess programming because of the limitations set by the hardware that was
available; however most modern chess engines will use a search algorithm that is much
closer to Type A but will have some aspects of selectivity to increase the efficiency.
2.2.2. Minimax
Minimax is a recursive algorithm used in turn based games in order to find the path
through a tree with the highest value for a certain player (Beal, 1980). In chess it works
by declaring one side, generally white, as the ‘maximising’ player and the other as the
‘minimising’ player. Appendix A shows the pseudocode of one potential implementa-
tion of the minimax algorithm, however it can be split into two separate functions: a
maximising search and a minimising search. Minimax is what is called a depth first
recursive algorithm that will traverse to the furthest node in a branch before evaluating
back up the tree. As there is no heuristics involved in the minimax algorithm, it could
be classed as purely Type A and therefore will not be efficient at higher depths.
2.2.3. Alpha-Beta Pruning
In order to improve the efficiency of the minimax algorithm, some logical analysis or the
search can be applied to reduce the amount of discrete branches that need to be checked.
A common enhancement to the minimax algorithm is called alpha-beta pruning, which
aims to reduce the amount of search paths by excluding certain branches from the search
tree (Edwards and Hart, 1961). As seen in Appendix B, an upper and lower limit (alpha
and beta)are used to prune branches when a move is found with a lower heuristic value
than a previously tested move. This works well as it forces the engine to focus on the
more prosperous routes through the search tree which lowers each total processing time
of the search (Knuth and Moore, 1976).
2.2.4. Further Optimisation
Further optimisations can be made to the algorithm by ordering the moves to be searched
so that the moves that the best move for the each side are searched first, (Fulda, 1985).
Reg: 4692306 13
![Page 14: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/14.jpg)
CMPC3P2Y
The ordering can be achieved in several ways, one is to use the killer move heuristic
where a list of moves that cause a beta cut-off and do not alter the material on the board
are stored and updated after each iteration; these moves are searched first, followed by
the remaining moves.
2.3. Evaluation Philosophies
The final key component of any chess engine is it’s ability to distinguish the differ-
ence between a good move and a bad move. The evaluation function must be able
to heuristically determine the chances of winning after n moves have occurred. Non-
expert human players perform this by assigning arbitrary values, or material weight, to
the individual pieces and this is also how the chess engine will begin to approach the
problem. To ensure that the engine runs as efficiently as possible, the evaluation needs
to be as lightweight as possible while still providing a meaningful output in relation to
the chances of winning.
2.3.1. Performance Balance
All evaluation functions need to make compromises with the intelligence they possess
as there is a negative correlation between speed and knowledge; as the engines ability to
recognise the difference between a favourable and an unfavourable result, the amount of
time it takes to make the decision increases. This means that attention must be paid to
keeping the execution time of the evaluation to an absolute minimum. Another advan-
tage of using a more lightweight evaluation is that they are far more maintainable when
compared to more complex heavier evaluations, which is important due to the intricate
nature of a chess engine.
2.3.2. Game Phase
Another factor that needs to be taken into account when writing an evaluation is game
phase. Any game of chess will begin in the opening phase, where each side will need
to set up their pieces to enter the middle game in a strong position. The opening phase
typically lasts around 7 or 8 moves for each side and during this time each side will
Reg: 4692306 14
![Page 15: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/15.jpg)
CMPC3P2Y
want to move pieces into more advanced positions on both edges of the board, develop
the knights and create a defence for their king. As the black side is purely comprised of
pawns, the last two points are not applicable and should be ignored.
Once the opening phase is over, the game moves into what is called the middle phase
or the middle game. This is the largest phase of the game where the majority of the
battle will take place. Players should be looking to limit the mobility of the opponents
pieces while maximising their own and placing pressure on the opponent that will open
up future opportunities to attack. An aggressive play-style during this phase is vital as
the aim is to defeat the other player; however, it is crucial that each player maintains as
many of their key pieces as possible to take into the endgame.
During the final stage of the game, the endgame, there are few pieces left on the board
and the relative value of each type of piece changes. It is often difficult to determine
the exact point where the endgame begins as the transition could occur progressively
or within a matter of a few captures. Throughout the endgame, until a result is found,
pawns become a more valuable piece because the open nature of the board makes pro-
moting a pawn through the highest rank into a more mobile piece far easier. This process
is made less difficult for the side with the largest amount of material value as they can
exchange pieces, whilst retaining the maximum amount of pawns possible, which will
result in a greater chance of winning. Another piece that gains significant attacking
value is the king itself, which can be moved into the central area of the board in order
to use its potential properly. Whilst the king does gain value in an attacking sense and
it is a useful tactic in the endgame, careful consideration must be used because a game
can quickly turn on one mistake.
2.3.3. Shannon’s Evaluation
A journal article written by Claude Shannon (Shannon, 1950) provides a symmetric
evaluation function that takes into account the material value, mobility and information
about the pawns on the board, as can be seen in Appendix C. This evaluation function
is tailored to western chess and it is important to take this into account when developing
an evaluation for Horde chess; however, this is a useful starting point for the function to
be used in the engine.
Reg: 4692306 15
![Page 16: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/16.jpg)
CMPC3P2Y
3. Analysis of Horde Chess Strategy
Horde chess provides an interesting challenge for the strategic decisions that the chess
engine makes because of the relatively minute amount of content on the subject when
compared to Western chess. While some common tactics could still be used, particu-
larly with white defensive moves, it is clear that fresh concepts need to be examined
(Bourzutschky et al., 2005). In order to analyse which methods could possibly yield a
positive outcome an analysis of the differences in risks for each colour and the strengths
and weaknesses of the pieces that they possess can be performed.
3.1. White Strategy
The white side arguably faces the easiest task, as it has a greater variance in the type
of piece in it’s ranks and thus opens up more strategic options to the engine. An obvi-
ous example of this is that the white side has a multitude of pieces that can move more
than one square in one move, unlike the black side which is composed purely of pawns.
Furthermore, white has two knights which have the ability to jump other pieces which
makes them hard to block. These obvious advantages towards white have been balanced
by the sheer number of opposition pawns, however the pawn has a fundamental weak-
ness that the white side can take advantage of. The movement characteristics of the
pawn dictate that they can only take an enemy piece if it is in a diagonally adjacent tile,
or move one tile forward providing said tile is empty; this is the case unless the pawn
is in the second rank, where it can also move two tiles forward under the same premise
that the tile is empty. The implication of this is that if white can move a piece that can
take opposition pieces in a lateral movement, or in the direction that the black side is
attacking, the piece will be able to continuously take pawns without any risk of being
taken. Therefore a rook, queen, bishop or, less so, a knight behind the opposition pawns
should have a higher value than it would if it were in front.
It is also important to note that if a black pawn reaches the highest rank it can be
promoted to any piece other than a king; generally the pawn will be promoted into a
queen, the most valuable piece available. This suggests that it would be beneficial to
block pawns from advancing to rank 8 and promoting into a piece that could potentially
Reg: 4692306 16
![Page 17: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/17.jpg)
CMPC3P2Y
swing the game in favour of the black side. This is exceptionally important during the
endgame as promoting pawns becomes much easier and the general attacking potency
of the pawn increases during the final period of the game.
3.2. Black Strategy
Considering the simplicity of the movement characteristics of a pawn, the strategic plan-
ning for the horde of pawns on the black side proposes an interesting challenge. The
clear place to start with developing these strategies is by countering the strategies that
white are going to use by looking to prevent pieces from getting behind or parallel with
the lowest ranked black pawns. This can be achieved by maintaining as many pawns
as possible in the two bordering columns on either side of the board with priority being
given to pawns in columns 1 and 8.
It is crucial that the black side remains attacking in defence which be achieved by
trying to ensure that any pawn is always covered by another. With this tactic in place,
any white piece that takes a pawn can be instantly exchanged. This does not work in
every possible situation, for example if the pawn that is taken is one of the lowest ranked
pawns, but could still increase the chances of winning and the overall skill of the black
side.
In terms of capturing the king during the endgame in order to win the match, the main
aim should be to promote as many pawns as possible into queens. The issue of how to
produce this effect algorithmically in the chess engine is not simple and the limitations
of the engine cause some problems. For example at a depth of 5, the black side can
only forecast the next three moves for its own pieces and a potential promotion could be
out of this visible range. A solution can be achieved by gradually making pawns more
valuable as they increase in rank during the endgame. However, there may need to be
some consideration for the safety of a promoted pawn. If the white side has a rook or
queen on its first rank the newly promoted pawn would be taken in the next move if left
unprotected. Because of this, a pawn that has just been promoted but is protected by
another pawn should be worth more if the promoted pawn is under threat.
Reg: 4692306 17
![Page 18: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/18.jpg)
CMPC3P2Y
4. Engine Development
The project aim describes the design and implementation of a chess engine, with the
use of a variant being preferred, using any language of choice. When choosing the most
suitable programming language, the desired attributes need to be considered. A suitable
language needs to have a fast execution time, low overhead and good readability. These
properties suggest that C++ would be a good match for the task as, unlike a language
like Java that runs on the Java Virtual Machine, one of the key philosophies of C++ is
that the source code gets compiled directly into assembly code (Stroustrup, 2007). Other
benefits of C++ include it’s efficiency, flexibility and low level memory management.
4.1. Board
With the language decided, the next task is the implementation of the chess board. The
board is declared as a 2-dimensional array of integers where each piece type and colour
combination represents an integer that can also be accessed through an enumeration
of pieces. Using the enumeration gives the programmer an simple way of mapping
a machine-readable format to a human-readable format; for example simply using the
integer 10 as a piece value gives no hint to which piece it is, whereas P_W = 10 helps
to show that the integer 10 is linked to a white pawn. Benefits of using a 2-dimensional
array as the board include random access to the array, allowing for fast access to any
square on the board.
To further improve readability, the code takes advantage of structures, or struct,
which can be used to model and provide simple functions to smaller components of
the engine. An example of this is the use of a structure to simulate a position on the
board and supply a function that returns the string value of said position; for instance
the starting position of the white king, which could be accessed using board[4][0],
would return a string value "e1".
In order to analyse the effects on the bias towards a certain team, a mechanism for
changing the board set-up needs to be created. A basic approach to initialising the board
array would be to hard-code the values into the code itself, which would work well in
circumstances that did not require any changes to the board. To create a more dynamic
Reg: 4692306 18
![Page 19: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/19.jpg)
CMPC3P2Y
20,30,40,50,60,40,30,20
10,10,10,10,10,10,10,10
-1,-1,-1,-1,-1,-1,-1,-1
-1,-1,-1,11,11,-1,-1,-1
11,11,11,11,11,11,11,11
11,11,11,11,11,11,11,11
11,11,11,11,11,11,11,11
11,11,11,-1,-1,11,11,11
Figure 6: The default board structure for horde chess as declared in the initialisation text
file
system, the engine reads a text document that declares each piece in the board, which
can be seen in Figure 6, converting these values into the correct piece type through the
use of the enumeration previously described and placing them in their respective array
position. With this, several different piece arrangements can be used without the need
to recompile.
4.2. Search
Before being able to search for an optimal move, a method of accessing a list of all avail-
able moves must be created. There are two abstract approaches to this issue: real-time
move generation and a predefined list of possible moves. The problem with producing
the move list at runtime is that, because of the large amount of moves available, it takes
a relatively large amount of processing time which could be spared by using a prede-
fined list. A more suitable approach for the high efficiency requirements of the chess
engine, is to predefine the moves by saving them into files in a format that can be read
into the chess engine when the application is run. A separate application can be written
that works out all possible moves for each piece type, formatting the moves and saving
them to a text file for each piece-colour union. The engine reads each of these files as
part of the initialisation stage and places them into a map structure where the key is the
position of the piece and the value is a vector of all possible moves that the piece can
Reg: 4692306 19
![Page 20: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/20.jpg)
CMPC3P2Y
make from this square of the board. The disadvantage of using this technique is that
the list of moves generated does not consider any factors that cause certain moves to
become invalid; an example of this is that a pawn, which can only take diagonally, will
not be able to make any of it’s possible moves if there is an enemy directly in front and
the diagonal spaces are either empty or holds an ally piece. This means that some extra
processing must be performed to ensure that each move is valid before considering it
as the best move. This can be done by running each move through a set of specific
algorithms designed to determine the legality of a move for each piece type. While this
extra processing does incur a small amount of overhead, but this addition is far lower
than the load associated with real-time move generation.
With a suitable system for determining all of the valid moves, the implementation of
the search algorithm can begin. The algorithm that the engine uses is a slight variation
on the minimax algorithm, with the difference being that neither team is exclusively
associated as the maximising or minimising player. Instead, all evaluations are worked
out as a relation to the player taking the current turn throughout all depths; effectively
the current turn is always the maximising player. There are three functions that are
defined in the program: findBestMove, minSearch and maxSearch. The initial
call to perform a search at a specific depth is simply, findBestMove(depth);,
which will begin traversing the board tile by tile. For each tile, the engine will find and
check the validity of all moves possible for the piece type of the tile occupant using
the current index as the key to the map of moves. The use of the unordered_map
data type, which has a worst case access of O(log n) and a best case of O(1), provides
excellent access speeds which is important due to the vast number of discrete calls to the
moves vectors. The move is temporarily performed on the board, with the destination
square being saved in case of a capture, before calling maxSearch with a decremented
depth. This function will perform a similar logic to the previous by finding, validating
and making a move then calling minSearch. This will continue until the depth reaches
zero when an evaluation takes place, hence the bottom-up classification of the algorithm.
Appendix B shows that once the evaluation occurs the value is checked against either
alpha or beta, depending on whether a min search or a max search is being performed. If
the beta value falls below the alpha value, the move is certainly worse than a previously
Reg: 4692306 20
![Page 21: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/21.jpg)
CMPC3P2Y
tested node and can be disregarded. After the value has been established, the move must
be reversed before testing the next move in the vector. Once all tiles on the board have
been tested, the findBestMove function returns the best move and performs it on the
board.
4.3. Evaluation
The evaluation method is loosely based on Claude Shannon’s evaluation function, shown
in Appendix C, and is used to produce a metric on a particular side’s chances of winning.
The engine first calculates a material weight by iterating through the board and summing
the value of each element. The value is generated by accessing an unordered_map
of evaluation scores where the index is the unique piece type and the value is the rela-
tive value of the piece. The pieces may be worth different amounts depending on their
colour; for example, a white pawn is worth 1 point and a black pawn is worth 2 points.
There are some special exceptions to the normal evaluation values that append the more
intricate strategic manipulation described earlier in the report. A white piece that is be-
hind or level with the lowest rank pawn or a black piece that is positioned in either a
border column or at it’s highest rank is worth one more point than the usual piece value.
int r = rand() % 3 - 1;
if (weight == WHITE)
{
int materialScore =
whiteScore * (whiteScore - blackScore);
int mobilityScore =
whiteMobility * (whiteMobility - blackMobility);
return materialScore + mobilityScore + r;
}
Figure 7: Calculating the evaluation score
As well as the material worth, the evaluation function computes the mobility of pieces
by traversing the board and totalling the sum of moves available to each piece on the
Reg: 4692306 21
![Page 22: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/22.jpg)
CMPC3P2Y
board for each colour. Once each team has a total value, the difference is calculated de-
pending on the current player to move using the method shown in Figure 7. To add some
variance to ‘computer vs computer’ games, a random offset is added to each evaluation
that ranges between -1 and 1 inclusively. This is necessary because the algorithm would
always find the best move possible, which doesn’t ever change and every game would
play exactly the same as the previous. The variance is small enough so that it is highly
improbable to pick a move that is significantly worse than the best possible move.
4.4. Graphical User Interface
A popular method of supplying a chess engine with a GUI is to include support for the
Chess Engine Communication Protocol which allows the engine to be executed by com-
mon chess interfaces, WinBoard (Windows) and XBoard (Linux). This method would
be preferable as the project did not require that an interface be created for the engine;
however, because of the relatively low uptake of the game-type, these interfaces do not
support Horde chess. The consequence of this is that, to be able to effectively use the
chess engine, a graphical user interface must be designed. During the development of
the engine the interface is not hugely important and a simple console GUI was temporar-
ily used. This allowed for the development of the underlying engine with the intention
of implementing a more graphical system after the completion of the engine.
When designing the final GUI, there are two options that were possible: creating a
standalone application that communicates with the engine or building a graphical user
interface directly on top of the engine. Of these options, the most elegant approach
would be to build a separate application that uses the Chess Engine Communication
Protocol to communicate with the engine; however, the complexity of implementing
this would not be a great use of time considering that it is not a requirement for the
project. A more time-manageable approach is to use a C++/CLR Windows Form with an
improvised game-loop, which can be seen in Figure 8. This does not produce a perfect
solution to the problem because the interface will remain unresponsive throughout the
computer player’s thinking time and this approach does seem to add some overhead due
to the mix of managed and unmanaged code.
Reg: 4692306 22
![Page 23: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/23.jpg)
CMPC3P2Y
Figure 8: Final Graphical User Interface
5. Evaluating Chess Engine Performace
The changes that were made to the overall design of the engine, due to the incompatibil-
ity with the intended GUI (WinBoard), introduced a considerable amount of overhead.
Table 2 states the average move execution times for each depth over a period of twenty
games with a late build of the engine and clearly shows that playing at a depth of 5 is
unacceptable with average move times of over a minute. A system must be implemented
to reduce the amount of work performed in each move.
5.1. Build Optimisation
One method of optimisation is to change the build settings available in Visual Studio
2013 to suit the needs of the program. Visual Studio provides certain automatic optimi-
sations which can be set to improve C++ code efficiency, the final build settings can be
seen in Figure 9. As well as these settings, the options allow the debug information to
Reg: 4692306 23
![Page 24: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/24.jpg)
CMPC3P2Y
Table 2: Move Execution Times - Late Build (Running on AMD FX-4100 3.6GHz - Single Thread)
Depth White Average (ms) Black Average (ms) Move Average (s)
1 15.1 12.6 0.0139
2 491.7 287.9 0.389
3 6397.9 4635.4 5.56
4 22456 19744.1 21.1
5 64326.8 55987.5 60.2
be taken out completely for release builds which should improve the speed of execution.
These changes improved the times, but only slightly and certainly not to an acceptable
standard.
5.2. Code Optimisations
Re-factoring code is an important part of programming to ensure the maximum effi-
ciency. After parsing the code for potential changes, several instances where code can
be improved become apparent. The use of the Visual Studio Performance Analysis fea-
ture helped identify the individual function calls that are either called the most or the
took the most processing time. From this data, changes were made to simple functions
that were called frequently; for example isEnemyPiece was condensed from 4 sepa-
rate lines of execution to a simple logical function taking advantage of the parity of the
pieces. Changes were also made to larger functions called slightly less often by adapt-
ing the data types used. Again these changes yielded insignificant results and it is clear
that a different approach is necessary.
5.3. Transposition Table
A common way of reducing the load on a search function in position based games is
the use of a transposition table which stores a hash of all previously searched positions
against the value they are worth. This means that any unique position that can be ac-
cessed via more than one combination of moves need only be evaluated once.
Reg: 4692306 24
![Page 25: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/25.jpg)
CMPC3P2Y
Figure 9: Visual Studio 2013 Ultimate Build Settings
Implementing this in the engine is a relatively simple task by utilising a function
that hashes the 2D board array, the current depth and the current turn. It is impor-
tant to hash the depth and turn data also as the engine would simply perform the
best move sequence after searching once and not search to the correct depth and with
the search wrong score weighting. This integer hash is then used as the key of an
unordered_map<int,int> object and the value is sourced from the best score
at this depth. With the transposition table filling up as moves are searched, positions
that have already been evaluated will begin to rise; for example, when a combination
of moves are performed in a different order they will result in the same final position.
Before searching for the next depth, the engine will check the transposition table for a
value and if found, the branch does not need to be searched again.
The results after the implementation of the transposition table, which can be seen in
Table 3, show a significant decrease in execution time. At a depth of 4, there was a
decrease in the average move time by 20 seconds from 21.1s to 1.19s. At a depth of
Reg: 4692306 25
![Page 26: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/26.jpg)
CMPC3P2Y
Table 3: Move Execution Times - Final Build (Running on AMD FX-4100 3.6GHz - Single Thread)
Depth White Average (ms) Black Average (ms) Move Average (s)
1 1.1 0.4 0.00075
2 25.7 9.8 0.0178
3 157.2 68.8 0.0802
4 1570.5 800.8 1.19
5 14840.3 7597.4 11.22
5, the average move reduced by over 81% from 60.2 seconds to 11.22 seconds. These
results bring the execution time of the engine down to an acceptable level at the desired
depth of 5.
6. Evaluating Horde Chess Equality
The major issue with Horde chess is the bias between the two sides, with the majority of
games favouring white; a competent player using white would have to make a consid-
erable error to lose with the current standard board set-up. The purpose of building the
engine is to analyse slight variations of the board in order to determine a better balanced
piece arrangement.
A series of tests are conducted, initially on the original board set-up to demonstrate
the bias between the two teams and then moving onto several different adaptations. Each
test consists of 50 matches with depths up to 3 with the result of every match at each
depth being recorded. A limit is set on the depth due to the time constrains of running
such large amount of matches, with 200 matches being played per board set-up.
6.1. Original Board Set-Up
The results of the original board set-up, as shown in Table 4, clearly show a bias towards
white as the intelligence of the engine increases. At depth 0, the black side has a clear
advantage which could likely be attributed to the quantity advantage it holds over white.
Reg: 4692306 26
![Page 27: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/27.jpg)
CMPC3P2Y
The would happen because when the computer is only considering it’s own move, the
majority of captures will be simple exchanges. Because of these results, this depth will
not be considered in future tests. This advantage is negated once the depth is raised to
1, with white winning 98% of matches. The win percentage for white does decrease
slowly as the depth is raised but the black win percentage does not rise at the same rate,
with the best part of the white wins converting into stalemates caused by black having
no valid moves. From viewing the final board states of each of these games, white were
in the most prosperous position by leaving black with no more than 4 blocked pawns.
Table 4: Original Board Analysis Results
Depth White Black Stalemate White Win % Black Win %
0 0 50 0 0% 100%
1 49 1 0 98% 2%
2 43 2 5 86% 4%
3 40 3 7 80% 6%
6.2. Board Adaptations
With the tests that prove the existence of the bias towards white complete, some board
adaptations can be tested. There are several ways to adapt the board in the attempt
of giving black a better chance of winning. Using the strategic knowledge that has
been gathered and noted earlier in the report, several promising board adaptations are
analysed.
6.2.1. No Extra Pawns
Ideally, a balance can be achieved without adding any extra pieces to black. The first
adaptation, as seen in Figure 10, is based on the premise that black needs to protect the
columns on either side of the board to help prevent a white rook or queen developing
down the edges and positioning behind the lowest ranked pawn.
Reg: 4692306 27
![Page 28: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/28.jpg)
CMPC3P2Y
Figure 10: Alternative board arrangement with no extra pawns
The results, as shown in Table 5, clearly show that this adaptation is worse than the
original in terms of game balance. At every depth the white win percentage increases
and the black win percentage decreases. This suggests that, while protecting the outer
columns is important to prevent the rooks advancing, the center of the board is of greater
significance than previously thought and the two pawns at D4 and E4 should remain.
Table 5: Alternative Board Arrangement Analysis Results - No Extra Pawns
Depth White Black Stalemate White Win % Black Win %
1 50 0 0 100% 0%
2 44 2 4 88% 4%
3 45 1 4 90% 2%
6.2.2. Two Extra Pawns
From the previous tests, it is evident that simply moving the arrangement of pawns
available will not be enough to affect the balance in the way required. One of the key
weaknesses of the black side is the lowest rank of pawns. In the original set-up, there is
a two tile gap at D8 and E8 where the pawns have been moved to D4 and E4. By placing
Reg: 4692306 28
![Page 29: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/29.jpg)
CMPC3P2Y
two extra pawns, as seen in Figure 11, in these two tiles the game should become less
biased towards white and a higher black win rate should emerge.
Figure 11: Alternative board arrangement with two extra pawns
Table 6 shows that at a depth of 1, there is an increase in black wins from 2% to 6%
and a decrease of 8% from 49 to 45 wins. At a depth of 2 the black wins increased
from 4% to 10%, while the white wins again decreased from 43 wins to 41. The largest
change can be seen at a depth of 3, with black’s win percentage rising by 10% to 16%,
white’s win percentage falling from 90% to 70% and Whilst this is a positive start, there
is still a considerable bias towards white and further changes to the board seem to be
necessary.
Table 6: Board Alternative Analysis Results - Two Extra Pawns
Depth White Black Stalemate White Win % Black Win %
1 45 3 2 90% 6%
2 41 5 4 82% 10%
3 35 8 7 70% 16%
Reg: 4692306 29
![Page 30: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/30.jpg)
CMPC3P2Y
6.2.3. White Pawn Handicap
An alternative approach to changing the balance is to handicap the white side by re-
moving a pawn, Chess-Video et al. (2010). As seen in Figure 12, while keeping the
previous change that slightly increased the win percentage of the black team, the white
pawn originally positioned at F2 has been removed, exposing the king. This is the only
viable pawn to remove as it does not increase the initial mobility of white; the pawn had
2 moves initially, the kings mobility increases by 1.
Figure 12: Alternative board arrangement with a white pawn handicap
The final arrangement that was tested shows the most convincing results, which can
be seen in Table 7. At depth 1, there is a slight decrease in the amount of black wins
from 3 wins to 2, while the white wins increase from 45 to 46. This trend does not
continue as the depth increases however, with white wins dropping by 4% from 41 to 39
at a depth of 2. The black wins, at a depth of 2, increase by 2% from 5 wins to 6. It is at
a depth of 3 where the most persuasive evidence materialises. The white win percentage
hits the lowest value during testing at 70% while the black wins peak at 20%.
Reg: 4692306 30
![Page 31: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/31.jpg)
CMPC3P2Y
Table 7: Alternative Board Arrangement Analysis Results - White Pawn Handicap
Depth White Black Stalemate White Win % Black Win %
1 46 2 2 92% 4%
2 39 6 5 78% 12%
3 35 10 5 70% 20%
7. Conclusions
Horde chess proved to be a proved to be a proficient choice as it not only offered an
interesting concept that has not been greatly researched, but it also granted the oppor-
tunity to analyse a clear bias towards the white team. Using C++ as the language to
implement the chess engine, instead of other common languages Java and C#, was the
correct decision due to the need for efficiency. From the implementation of an array
based board it seems that it would be an interesting study to review the performance
differences between piece centric and square centric board representations by imple-
menting bit-boards into the engine. Due to the experience that was gained from devel-
oping the engine, it would be a more comfortable task to perform again without the need
for the readability benefits. The algorithms that were used as a template for the move
searching function were adapted slightly over the course of the development and in turn
there is likely some further optimisation that could be performed to further improve the
engines efficiency. The evaluation function, based on Shannon’s original evaluation,
demonstrated competent results with a small amount of processing time. The GUI that
was implemented caused an unexpected amount of overhead because of the use of both
unmanaged and managed code. An alternative solution would be to create a separate
application that communicates with the engine running in it’s own process. This would
likely further decrease the times of each move but unfortunately this was not feasible
in the time available. One of the advantages to using the C++/CLR Forms API was the
ease of adding controls, which enabled invisible buttons to be placed in a grid for the
human players moves.
The results of the analysis performed have shown that it is possible to enhance the
Reg: 4692306 31
![Page 32: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/32.jpg)
CMPC3P2Y
balance of the chess variant, Horde chess. However, the results are not clear enough
to provide a definitive way to create a close to 50:50 bias and more testing of different
board adaptations will need to be performed to achieve this. The best arrangement in
terms of balancing was a combination of filling the void spaces at the back of the pack
with two extra pawns and giving the white team a pawn handicap by removing the piece
at F2. This yielded the results shown in Table 7 that state a 70% win rate for white, a
decrease from 80% for the original board; the black team increased from 6% to 20%.
Figure 13: Close-up to show moves and times at a depth of 5
With regards to efficiency, there were some unexpected barriers that needed to be
acted upon. The original plan was to integrate the engine with the popular GUI Win-
Board to ensure that the engine can run to it’s full potential. This would not work due to
the incompatibility with the variant selected and a GUI would need to be built to work
with the engine. The GUI that was created added a significant amount of overhead and
Reg: 4692306 32
![Page 33: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/33.jpg)
CMPC3P2Y
increased the execution times of moves due to the mixing on managed and unmanaged
code. A transposition table was implemented to reduce the amount of duplicate eval-
uations and the results can be seen in Table 3. These changes allowed the engine to
perform at a good standard, searching 5 ply moves in an average of 11.22 seconds, as
can be seen in Figure 13.
Reg: 4692306 33
![Page 34: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/34.jpg)
CMPC3P2Y
References
Beal, D. F. (1980). An analysis of minimax. Advances in computer chess, 2:103–109.
Bourzutschky, M. S., Tamplin, J. A., and Haworth, G. M. (2005). Chess endgames:
6-man data and strategy. Theoretical Computer Science, 349(2):140–157.
Chess-Video, B., Stewart, C. V.-N., and Gulamali, F. (2010). Chess variant.
Edwards, D. J. and Hart, T. (1961). The alpha-beta heuristic.
Fulda, J. S. (1985). Alpha beta pruning.
Hyatt, R. M. (1999). Chess board representations. Online Technical Papers, 49.
Knuth, D. E. and Moore, R. W. (1976). An analysis of alpha-beta pruning. Artificial
intelligence, 6(4):293–326.
Rasmussen, D. (2004). Parallel chess searching and bitboards. PhD thesis, Technical
University of Denmark, DTU, DK-2800 Kgs. Lyngby, Denmark.
Shannon, C. E. (1950). Xxii. programming a computer for playing chess. The
London, Edinburgh, and Dublin Philosophical Magazine and Journal of Science,
41(314):256–275.
Stroustrup, B. (2007). Evolving a language in and for the real world: C++ 1991-2006.
In Proceedings of the third ACM SIGPLAN conference on History of programming
languages, pages 4–1. ACM.
Reg: 4692306 34
![Page 35: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/35.jpg)
CMPC3P2Y
A. Minimax Algorithm Pseudocode
function minimax(move, depth, isMaximisingPlayer)
if depth = 0 or there are no more possible moves
return evaluation(board)
if isMaximisingPlayer
bestValue := -INFINITY
for each possibleMove in allValidMoves
tempValue := minimax(possibleMove, depth - 1, false)
if tempValue > bestValue
bestValue := tempValue
return bestValue
else
bestValue := +INFINITY
for each possibleMove in allValidMoves
tempValue := minimax(possibleMove, depth - 1, true)
if tempValue < bestValue
bestValue := tempValue
return bestValue
Reg: 4692306 35
![Page 36: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/36.jpg)
CMPC3P2Y
B. Alpha-Beta Pruning Algorithm Pseudocode
function minimaxAB(move, depth, alpha, beta, isMaximisingPlayer)
if depth = 0 or there are no more possible moves
return evaluation(board)
if isMaximisingPlayer
value := -INFINITY
for each possibleMove in allValidMoves
value := max(value, minimaxAB(move, depth - 1,
alpha, beta, false))
if value > alpha
alpha = value
if beta <= alpha
break
return value
else
value := INFINITY
for each possibleMove in allValidMoves
value := min(value, minimaxAB(move, depth - 1,
alpha, beta, true))
if value < beta
beta = value
if beta <= alpha
break
return value
Reg: 4692306 36
![Page 37: Development of a Chess Engine](https://reader031.vdocument.in/reader031/viewer/2022012101/61db8593ad96f00b0745b313/html5/thumbnails/37.jpg)
CMPC3P2Y
C. Claude Shannon’s Evaluation Function
f(p) = 200(K-K’)
+ 9(Q-Q’)
+ 5(R-R’)
+ 3(B-B’ + N-N’)
+ 1(P-P’)
- 0.5(D-D’ + S-S’ + I-I’)
+ 0.1(M-M’) + ...
KQRBNP = number of kings, queens, rooks, bishops, knights and pawns
D,S,I = doubled, blocked and isolated pawns
M = Mobility (the number of legal moves)
Reg: 4692306 37