Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Registration number 100051751
2016
Constructing a Chess Engine in the JavaProgramming Language
Supervised by Gavin Cawley
University of East Anglia
Faculty of Science
School of Computing Sciences
Abstract
This dissertation examines and explains the Chess Engine project. The project aimed
to create a simple and powerful chess engine within the java programming language.
Previous examples of other projects were considered and formed a strong foundation
for the direction that this project took. Various optimisations have been explored and
explained within the paper. Improvements were adopted in the project attempting to im-
prove the performance without sacrificing accuracy or stability. A less object-orientated
approach was taken during the project in order to try and boost performance, by remov-
ing the overhead. Observing that this project was programmed in the Java programming
language showed that it severely limited the capabilities of this project. Similarly the
Non-OO aproach meant that the code base was very difficult to manage. Hoever this
project reached completion.
Keywords Java, Chess, Recursive, Narrow AI, Algorithm, Alpha-Beta Search
Acknowledgements
The kind stranger who advised me to re-format the board to be more readable, many
thanks.
CMP-6013Y
Contents
1 Introduction 5
1.1 Project Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Potential issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 Context 8
2.1 Chess Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Chess History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Time Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Java Language background . . . . . . . . . . . . . . . . . . . . . . . . 9
3 Design and Methodology 10
3.1 Top Level Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Move Generation and Application . . . . . . . . . . . . . . . . . . . . 14
3.3 Move Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4 Outcomes and Analysis 23
4.1 Goals met . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.2 Timeline accurate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5 Conclusion 27
5.1 Java is a poor choice of language for this project . . . . . . . . . . . . . 27
5.2 Non-OO-programming difficulty . . . . . . . . . . . . . . . . . . . . . 27
5.3 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.4 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
6 Glossary 29
6.1 Chess Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
6.2 Programming Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
References 35
Reg: 100051751 iii
CMP-6013Y
List of Figures
1 Design Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2 Diagonal Edges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3 Special Moves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4 Blocks Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5 Alpha Beta Pruning . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6 Original Project Timeline . . . . . . . . . . . . . . . . . . . . . . . . 25
7 Actual Project Timeline . . . . . . . . . . . . . . . . . . . . . . . . . 26
8 Chessboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
9 UI Chess Pieces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
10 List of Chess Pieces . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
11 Chessboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
12 Starting Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
13 En Passant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
14 Castling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Reg: 100051751 iv
CMP-6013Y
1 Introduction
The aim of this project was to create a simple, yet powerful chess playing program
within the Java programming language. The first step to doing this was splitting the
workload of this project into various sections, each to be handled separately and then
pieced together nearer to completion. The way chosen to split the project was into
3 sections; Top Level Controller, Move generation and application, Move selection.
Although these sections vary drastically on code-base length and complexity, they each
have minimal dependence on each other, allowing for easier testing and debugging.
These different sections will be explained within the design and methodology section.
One of the other major advantages in this division of components is that they can be
easily replaced or updated with minimal impact on the other components. These facts
suggest that it is an appropriate model for an incrementally refined project.
1.1 Project Goals
This project is a large due to the recommended programming type being of a non-object-
orientated manner. This means that there will be a very large code-base which will need
to perform very well and maintain a good standard of error-checking throughout the
project. Some goals were created to help manage this large project and keep it on track
with the time-line by helping to minimise risk and have effective code. Note that none
of these goals need to be achieved in order to create a working Chess Engine, however
they would significantly improve the standards and performance of the game. All of the
project goals are as follows:
Efficient recursive code When the recursive algorithm is running, any code within
the path will be duplicated and add further calculations to the cycle. This means that one
summation added to the code could be repeated on every layer of the recursion, meaning
millions of repetitions; therefore it is vital to write simplistic and efficient code. Code
outside of the recursive calls should ideally still be simplistic and efficient, however it
makes a negligible impact upon the performance of the program in comparison.
Reg: 100051751 5
CMP-6013Y
Efficient elimination of weak outcomes This means that within the tree of possible
moves, any poorly scored branches are quickly and easily dropped, in order to reduce
the workload of the function. This pruning can be implemented and improved through
various means. Some simple ways of adding pruning are ordering the moves so that
more favourable moves are inspected first, so that a good comparison benchmark can be
set. From there further moves will be more easily eliminated as they will have a lower
probability of producing a higher score.
Solid rule enforcement This means that all of the game’s rules are strictly enforced
and there is no surpassing them. This is achieved by having an absolute path when
applying moves to the board and determining which moves are legal.
Full rule coverage This means that all the laws of chess by 84th FIDE Congress
(2014) are enforced to the letter. Meaning that rules such as three-fold-repetition, and
the fifty-move rule are in effect within the game. This full rule coverage means that the
game should meet FIDE standards.
1.2 Potential issues
This project has many potential issues that, if not addressed correctly, could drastically
affect not only the project time-line, but the complexity of the code itself.
Board Management Implementing a simple board that can allow for complex moves
such as castling and en passant, without cluttering the board or producing excessive
calculations is very difficult. A balance needs to be struck between containing all the
relevant information that the game needs, and keeping the board design simple and easy
to manipulate.
Accurate King Control Implementing a way for the king to know which tiles it cannot
move to, as those tiles would put the king in check and forfeit the game. This requires
knowing all of the enemy possible moves, including when an enemy piece is blocking
another, because if taken then the previously blocked piece could attack.
Reg: 100051751 6
CMP-6013Y
Evaluating the Board Finding a good evaluation technique is very important, as the
method chosen needs to be simple, yet give a fair and useful insight into how the game
is going at that stage in time. This value also needs to be applicable to the player whose
turn it is, otherwise the selection algorithm may have issue with the results.
Board Rules and UI Finding a way to easily determine whether rules such as the
three-fold repetition rule or the fifty-move rule have been violate during the game and a
stalemate allowed to be called. Also importantly with this aspect, if a human player is
playing, how are they able to recognise this pattern and how are they able to signal that
they wish to call a stalemate.
Java 32-bit Word Loads Due to the nature of Java Virtual Machine operation, com-
putations are done by loading in 32-bit words every time, so there is no significant
advantage to using bytes instead of integers. This lead to the very difficult situation
of trying to make efficient code, in a language not build for efficiency. This lack of
efficiency is due to the various check and safeguards that Java implements to prevent
massive errors.
Non-OO Project Also the fact that Java is an object-oriented based language makes
it very difficult to program large amounts of linear code. This means that most of the
optimisations that object-orientation would provide will be ignored within this project
as the recommended means of coding is in a non-object-orientated manner.
Reg: 100051751 7
CMP-6013Y
2 Context
2.1 Chess Basics
The game Chess consists of two opposing sides aiming to remove the other sideâAZs
king piece from the board. Each side start with 16 pieces of their sides colour placed in
their starting positions on the board (see glossary for more). Each side specifically has
8 pawns, 2 Rooks, 2 Knights, 2 Bishops, a Queen and a King piece. Each piece type has
its own unique move set that allows it to travel around the board. Most pieces cannot
pass through other pieces, with the exception of the Knight which is allowed to pass
over allied and enemy pieces alike. Although the main objective is to remove the enemy
king via capture, victory can also be achieved by the other side surrendering, or if the
game is timed, by forcing the other player to run out of time (see time control section
below). One side is referred to as the white side and the other as the black side (although
similar colours may be used). Other than these basic moves there are four special types
of moves, the initial forward-two pawn move, the En Passant attack, Castling moves
and Promotion.
2.2 Chess History
Chess is thought to be one of the oldest and most famous mental games, dating back
hundreds of years. However the first modern chess tournament was held in London in
1851 at LondonâAZs great exhibition. Around this time competitive chess became very
popular.
2.3 Time Control
In the years following on from the first tournament, time-oriented chess was introduced
due to players taking excessive amounts of time to plan moves, according to Soltis
(2002) Howard Staunton had proposed a monetary fine as a deterrent for players to
stop wasting time, this was tried but proved a poor deterrent for non-amateur players.
Instead forfeiture was regarded as a mandatory penalty after the Vienna 1882 games. If
Reg: 100051751 8
CMP-6013Y
this project has sufficient time and means to add a way of managing time control fairly
and accurately then it shall be added.
2.4 Java Language background
All of the Java Language information relevant to this project is actually summarised in
the Java Language Specification Introduction James Gosling (2015).
The Java programming language is a relatively high-level language, in that
details of the machine representation are not available through the language.
It includes automatic storage management, typically using a garbage collec-
tor, to avoid the safety problems of explicit deallocation (as in C’s free or
C++’s delete). High-performance garbage-collected implementations can
have bounded pauses to support systems programming and real-time appli-
cations. The language does not include any unsafe constructs, such as array
accesses without index checking, since such unsafe constructs would cause
a program to behave in an unspecified way.
This means that absolute control over this language is impossible due to, in-build safe-
guards, therefore any form of absolute efficiency within the program is very difficult to
achieve.
Reg: 100051751 9
CMP-6013Y
3 Design and Methodology
When planning out the design for this program the way I chose to split this project was
into 3 sections; Top Level Controller, Move generation and application, Move selection.
This diagram shows the basic outline of the project
Figure 1: Design Diagram
Reg: 100051751 10
CMP-6013Y
3.1 Top Level Controller
The "Top Level Controller" aspect of the project is the component that contains the
actual information about the board, its pieces and the games states; such as check/mate
and current turn. This involved documenting all aspects of the game that would function
on this level. Firstly the board needs to be represented in a reliable way that is easy to
manipulate. The model that I used for the board and pieces changed throughout the
project as I encountered problems and unforeseen pitfalls within the project. The initial
design was having a board that was an array of sixty-four bytes to represent the board
and the pieces to be one of the byte values, however within the Java virtual machine
bytes and integers are treated the same way when calculating values, so integers were
chosen instead to allow for more flexibility in development.
Initial Code Allocation When initially allocating the values for pieces anything neg-
ative was considered a blank tile and everything between zero and thirty-one were con-
sidered white pieces, whereas black pieces were from thirty-two to sixty-three. These
boundaries were defined by the constants W_START, which equals zero and B_START,
which equals thirty-two. From each of these start points the pieces were as follows:
PAWN = START + ONE
ROOK = START + TWO
KNIGHT = START + THREE
BISHOP = START + FOUR
QUEEN = START + FIVE
KING = START + SIX
Changes This initial set-up of values was thought to be sufficient to represent the
actual game pieces and states, however this actually changed to a different system in the
final variation of the pieces to include piece states. The final piece set adds these new
piece types:
UNMOVED PAWN - This piece is used to represent a pawn that has not been moved,
this differentiation from normal pawns allows the addition of the initial two-step forward
Reg: 100051751 11
CMP-6013Y
move and the addition of the complex function of the en passant move (see glossary)
in conjuncture with the Passant Shadow Pawn. It also allows for removal of promotion
checks on unmoved pawns and removal of en passant offensive move checks. This
reduces the load per cycle for calculating the moves of each player.
PASSANT SHADOW PAWN - This piece type represents the signaller that falls behind
an unmoved pawn that moves forward two. This signaller piece only exists for the
opponents next turn and is then wiped from the board, this signaller confirms that an en
passant move is possible within the appropriate time frame, however this piece is only
visible to enemy pawns, and so can be safely passed through or onto by other pieces.
When evaluating the board this piece is also seen as invisible and doesn’t affect the
score.
UNMOVED ROOK - This piece is used to represent a rook that has not been moved
yet in the game, this too reduces the load on calculating the moves, however the main
function of this piece type is in conjunction with the unmoved king piece for castling
availability. If the piece exists on the kingside or queenside of the starting rank of its,
colour then that type of castling is available as a move for the unmoved king piece, if
that piece exists.
UNMOVED KING - This piece is used to represent a king that has not been moved,
and is used to allow for castling rules in conjecture with the unmoved rook piece, this
piece has the extra castling moves, but check on king and queenside for the presence of
an unmoved rook of its colour on the starting rank. This allows a complex move to be
easily verified and added to the possible moves.
Code Re-allocation Each of these new piece types vastly reduce computational ex-
pense throughout the game by removing the need to be unnecessary bound checks or
piece checks. With the addition of these new pieces, the allocation of the values also
changed. The values are as follows:
BLANK = ZERO
WHITE PASSANT SHADOW PAWN = ONE
Reg: 100051751 12
CMP-6013Y
BLACK PASSANT SHADOW PAWN = TWO
UNMOVED PAWN = START + ONE
PAWN = START + TWO
UNMOVED ROOK = START + THREE
ROOK = START + FOUR
KNIGHT = START + FIVE
BISHOP = START + SIX
QUEEN = START + SEVEN
UNMOVED KING = START + EIGHT
KING = START + NINE
Start Value Changes Also the start values for W_START and B_START were changed
to thirty-two and sixty-four respectively. This choice was made simply to separate out
the three groups of BLANK TYPES, WHITE PIECES, and BLACK PIECES. Although
Passant Shadow Pawns are technically not entirely blank, they only act as non-blank un-
der special circumstances.
Board Rules The Top Level Controller also stores an Array-List of board data that
is relevant to the three fold repetition rule and the fifty-move rule, this array resets
whenever a pawn moves forward, or a piece is taken, as this means that board layout
cannot occur again during that game and therefore doesn’t need to be checked thereafter.
This pawn reset effect is due to the fact that pawns cannot move back and become
promoted on the final rank and so that pawn can never be in that position again.
Other Components The last parts of the top level controller are the Checkmate and
Stalemate checks alongside the board-printing methods and turn control. The Check-
mate and Stalemate variables are declared at the start of the program as false and after
the game ends determine the winner. The variables are checked within the main loop
before each move is made in order to determine if the game has ended. The Board print-
ing method call also lies within the main loop. There are two versions of this method, a
standard printing version that displays the pieces as they would actually exist and the de-
veloper printing version which prints all the added pieces as well. This distinction was
Reg: 100051751 13
CMP-6013Y
added to allow easier debugging and understanding to developers looking at how the
engine works. The turn control mechanic was kept simple and simply flips a Boolean
value after every turn.
3.2 Move Generation and Application
The "Move Generation and Application" section of the project is the bulk of the code.
This section contains a branch-like structure that controls which moves are possible and
another branch-like structure to handle applying them to both the main game board and
the various theoretical boards that are passed to it. This area of code works off a system
of move codes that had to be defined early on, but which were refined several times in
the project to incorporate special circumstances.
Place-holder Construction The first step in this section was to try and create a basic
place-holder move generator and applicator for the purposes of testing other sections.
This involved creating a way of recording possible moves, checking if those moves are
allowed and then, if chosen by the player, applied to the board.
Applying Move Codes The initial move code set was a simple solution meant to
tackle the vast majority of chess moves which abide by a simple rules which stay the
same throughout the game. The first codes used the last twelve bits of an integer to
define the code, this was split into two parts; the last six bits to show which tile the
move was being made from, and the second six bits which showed which tile the moving
piece was moving to. Six bits was the chosen amount because there are sixty-four tiles
on the board which can be exactly represented using six bits with starting index of zero.
This code system covered over ninety percent of all the moves available to make within
the game. This design was incorporated and developed to get a baseline system up and
running and to help test other sections.
Move Calculation Once the basic move set was determined the move calculation
method was added to find all the possible moves of the current turn’s player given the
current board state. This method worked by first checking who’s turn it is and then
Reg: 100051751 14
CMP-6013Y
cycling through the board to identify any pieces of the player’s colour and adding the
moves in the order that they were encountered. This worked by first checking if the
current tile was not blank, and then passing the tile into a switch statement which has
cases for all the pieces of that colour.
Pawn Move Case For the pawn case in the switch statement it simply had the offen-
sive diagonal forward, forward one and forward two moves. For the offensive moves
a check sees if any pieces of the opposite colour exist on the new tile; it uses the
W_START and B_START variables for this. Similarly the forward one and two check
to see if the tiles are unoccupied. For the purposes of this being a simple place-holder
move set the âAIJEn PassantâAI and promotion moves were not included.
Knight Move Case For the knight case, the piece is checked that it is at least two
squares from the board edge and then checks along the other non-diagonal axis if that is
at least one square away from the board edge. If both of these statements are true then
the two by one move is added, this is repeated for all 8 possible moves.
Rook Move Case For the rook case there were four loop structures that check the next
tile in their line. The four lines were forward, back, left and right. Before the loop is
entered there is a check that the rook is not at the edge of the board in the direction it
is trying to travel. Within each of the loops if the next tile is unoccupied then the move
to it is added and then starts to check the next tile. This process will continue until it
reaches the edge of the board if all tiles are blank. It knows it has reached the edge if the
next tile is specified by the edge constant stored in EDGES_FMIN/ EDGES_FMAX/
EDGES_RMIN/ EDGES_RMAX. EDGES_FMIN corresponds to the edge of the board
that is the lowest file and EDGES_RMIN is the lowest rank, and the opposite side for the
MAX constants respectively. The specific edge constant needed from the constant array
is determined in the F based arrays by the rank of the piece, and the R based specified
by the file of the piece. However if a non-blank tile is encountered then it checks if
that piece is an enemy, if it is then the move is added, otherwise it isnâAZt. After the
non-blank tile is encountered the loop stops as the piece is considered to be blocking
further advancement.
Reg: 100051751 15
CMP-6013Y
Bishop Move Case For the bishop case there is a similar process to the rook case
except for the fact that the directions and edge constants have changed. The directions
are now forward-right, forward-left, backwards-left and backwards-right. Similarly the
edge constant arrays have changed to EDGES_RMIN_FMIN, EDGES_RMAX_FMAX,
EDGES_RMIN_FMAX, and EDGES_RMAX_FMIN. However very importantly the
way these constant array are accessed changed. EDGES_RMIN_FMIN and EDGES_RMAX_FMAX
are specified by subtracting the rank from the file and adding seven. EDGES_RMIN_FMAX
and EDGES_RMAX_FMIN are determined by summing the file and rank (see figure
below for how these edge constant arrays work).
Reg: 100051751 16
CMP-6013Y
This figure shows the border values of the diagonal edges of the board
Figure 2: Diagonal Edges
Reg: 100051751 17
CMP-6013Y
Queen Move Case The Queen case is a combination of the bishop and rook cases
because the piece itself is a combination of both of their move sets. This meant that the
same code that is in each of those cases, was used in constructing the queen case.
King Move Case The King case was kept very simple in this place-holder version, it
included no castling move and no checking to see if the tile it was moving to would put
it into check. Also if the king was in check other pieces could still move, even if that
move would not stop the check. This version of the King case simply had eight moves,
one square in each direction. The king would check that the tile it was moving to was
on the board and that was it. Very interestingly when this place-holder King Case was
used with the Basic Alpha-Beta computer player it always made moves that wouldn’t
put the king in immediate danger as long as it had a search depth of at least two. This
phenomenon stemmed from the fact that the search function managed to successfully
determine that those actions would lead to a poor outcome and so ignored those moves
and moves that would not resolve check.
Move Application Once the place-holder move generation was complete the move
application counterpart needed to be created. This basic method took the move entered
as a move code integer and translated it into the "to" and "from" squares and subse-
quently applied the moves to the board given in the input. This place-holder method
was initially only about ten lines of code long as not much needed to be done.
After Place-holder After all of the place-holder components were complete the more
difficult moves could begin to be implemented, this involved fixing the king so that it
cannot move into check, making sure that check is resolved correctly, and implementing
all of the special moves. This involved extending the move code set to include "special
move" codes, building those moves into the various generation cases, creating a way of
finding which squares would put the king into check and extending the move application
cases.
Special Move Codes Firstly the extended move set still has the initial 12 bits dedi-
cated to positions on the board, however the values before that then determine the type
Reg: 100051751 18
CMP-6013Y
of move it is. This means any move that has a code higher than four-thousand and
ninety-six will be a special move. This means that the type of special move is deter-
mined by dividing the move code by four-thousand and ninety-six, which gives you the
values show in the figure below: The idea of these special codes was to act as markers
This figure explains the move codes for special moves
Figure 3: Special Moves
to the move application section which could then filter them out. The criteria for adding
these moves was determined in the move generation section, but the implementation of
how they actually work with the board is all handled in the application section.
The addition of the special moves and check handling drastically expanded the size of
the move generation method by about 400% this is dues to the addition of the "mine-
field" code, "block calculation" code and "In-check" code. These code blocks control
whether the king is in-check, or moving into check.
Minefield Code The minefield code section cycles through the board and finds oppo-
nent’s pieces, then it processes them via a similar switch statement to the normal move
handler. The switch statement gets the recognised enemy pieces and marks the possible
tiles that the enemy could move to on as so-called âAIJminefieldâAI board. The mine-
field board acts as an overlay for the current board being assessed marking danger spots
for the king. The minefield section also determines if an allied piece is directly blocking
an attack on the allied king and marks this in the blocks array. This array stores the tile
number of the blocking piece within the array positioned in the direction of the block as
the index (see diagram 4 below).
Reg: 100051751 19
CMP-6013Y
This figure explains the block array component of the move generation function.
Figure 4: Blocks Array
Block Calculation The information stored within the blocks array is then passed down
to the "block calculation" code section. This is a relatively small, but important section.
This section orders the blocks in ascending order to make processing easier. However
the original order is important to know which side of the king is being blocked, so
instead of actually re-ordering the array itself, a second array lists the indexes from the
original array in ascending value order. This allows the move calculation to know if
the current tile is blocking check, and so can handle it appropriately by sending it to
the "blocking moves" section instead of the normal move code. The blocking moves
code section is essentially the same as the normal move code, except that there are extra
checks to allow movement only in the axis that the piece is blocking the king in. Once
the blocked tile is processed the next lowest blocked tile is then processed when it is
reached within the board loop structure. This process is repeated until all blocks are
handled when the final tile to check is permanently set as negative one and so can never
be reached.
Additional Generation Cases The actual changes to the original code are minimal,
simply adding checks for each of the special move conditions and adding the checks
to make sure that the king doesn’t move into check, using the "minefield" board. The
addition of the new pieces to the move handler allows the original King, Pawn and Rook
cases to remain behind to handle general moves and segments of the code being copied
over. These special pieces have special moves such as Castling as well as the original
moves, however once moved Unmoved pieces become standard pieces. Passant Shadow
Reg: 100051751 20
CMP-6013Y
Pieces are automatically removed from the board after the full move is complete, to
prevent the enemy from capturing via En Passant after the immediate window.
In-Check Code In check is only accessed if the minefield code section marks one
of it’s target squares as being the allied king. This section simply looks through the
compiled list of moves and removes any that do not resolve check.
Returning Under normal circumstances the move list is simply returned as an array of
integer move codes. However if the case arises that there are no possible moves or both
kings do not exist on the boards then different return values are given. All valid moves
are positive numbers, so the special return codes used under these cases are all negative
or null. If a pair of kings do not exist then the returned value is null, this is an end state
for the search functions. If no moves are available, but the player is not in check then a
single negative one is returned, marking a stale-mate result. However if the player is in
check then a negative two value is returned marking a loss.
3.3 Move Selection
The Move Selection project section contains the User Interface, Basic Enemy and Alpha
Beta Search methods. Each of these methods take an in-putted board or just a set of
moves and pick one move to apply to the actual board.
User Interface This method simply is passed all the possible moves for the human
player in that turn and asks the human to enter the move that they wish to play. This
works by scanning in entered text from the console and extracting the from-to move
from the entered files and ranks. The error checker makes sure that the entered string
actually contains valid ranks and files, then check against the move list to see if it is
valid. If the move is valid it is applied, if not the method wait for valid input.
Basic Enemy This class acts as the simplest type of opponent in Chess, it simply
looks at the selection of legal moves available and randomly picks one. This requires
Reg: 100051751 21
CMP-6013Y
no evaluation of the board or predictions of enemy moves and acted as a place-holder
enemy.
Baisc Alpha Beta This class is the simplest implementation of the Alpha Beta algo-
rithm given in the figure 5 below.
The Alpha Beta Algorithm Stuart J Russell (1995)
Figure 5: Alpha Beta Pruning
This version of the Alpha Beta Pruning algorithm employs basic search and evalua-
tion functions. With the evaluation simply taking the material value of the board and
returning it.
Alpha Beta The more advanced Alpha Beta algorithm advances the search and evalu-
ation functions by ordering moves so that offensive moves are explored first and adding
evaluation tables to the scoring. The tables are individual to each piece type and cover
the whole board. the score is derived from each piece’s material value plus the table
score. These values are summed and returned.
Reg: 100051751 22
CMP-6013Y
4 Outcomes and Analysis
This project’s original aim was to create a simple, yet powerful chess playing program
within the Java programming language. This aim has been reached before the project
deadline, and so further development was added onto the project via extensions of the
evaluation functions and the addition of improvements to the UI.
Playable game of chess One of the outcomes of this project was the creation of a
relatively easily usable User-Interface, this interface is passed all the possible moves
from the main loop and awaits a user input. The user simple types the file and rank
of the square it is moving form and the file and rank of the square it is moving to. If
a non-valid move is entered then the inputted answer is rejected and the system waits
again for a correct user input. This allows the game to actually be playable by a human
player with ease.
AI move depth The best implementation of the Alpha Beta Search algorithm manages
to work to a depth of seven within a sufficient time-frame to consider it to be playable.
This is a reasonably good result
Win vs lose Of the various versions of the search algorithm, most of them could play
at least to an amateur level (with the exception of the Basic Enemy implementation)
and a few even to an intermediate level. This means that the search algorithm was
implemented sufficiently and the evaluation function is of a reasonably good standing.
4.1 Goals met
Efficient recursive code The code that is called during the recursive search function
attempts to minimise the amount of calculations done by making use of constants stored
in arrays, and by removing unnecessary checks that would add to the workload. This is
most of the optimisations that are available to this kind of code within the structure of
the code without removing essential code or re-engineering large portions of the project.
Reg: 100051751 23
CMP-6013Y
Efficient pruning The original Basic Alpha Beta Search had moderate pruning under
good conditions, however the more advanced Alpha Beta search algorithms improved on
this heavily by ordering offensive moves to be searched first and by utilising evaluation
tables for each of the pieces to guide them towards a better outcome.
Solid rule enforcement This goal was very difficult to prove completed as it required
repeatedly testing the code to make sure that all of the cases correctly allow or deny
adding moves to the available move list, based on circumstances of the board and other
pieces.
Full rule coverage Almost all of the FIDE laws of Chess were applied to the game
apart from the aforementioned time control rule, as this proved too difficult to implement
within the remaining time.
4.2 Timeline accurate
The original project time-line is shown in Figure 6 however the real project time-line
can be seen in Figure 7. There is a clear difference in these time-lines because of a
meeting where the discussion of the progress of the project at the time, indicated that
the project was headed in the wrong direction.
Reg: 100051751 24
CMP-6013Y
Proj
ects
ched
ule
show
nfo
re-v
isio
nw
eek
num
bers
and
sem
este
rwee
knu
mbe
rs
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
12
34
56
78
910
1112
CB
12
34
56
78
9E
B10
1112
Proj
ectp
ropo
sal
Lite
ratu
rere
view
Des
ign
Cod
ing
Test
ing
Cod
ede
liver
y
Fina
lrep
ortw
ritin
g
Insp
ectio
npr
epar
atio
n
Figure 6: Original Project Timeline
Reg: 100051751 25
CMP-6013Y
Proj
ects
ched
ule
show
nfo
re-v
isio
nw
eek
num
bers
and
sem
este
rwee
knu
mbe
rs
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
12
34
56
78
910
1112
CB
12
34
56
78
9E
B10
1112
Proj
ectp
ropo
sal
Lite
ratu
rere
view
Des
ign
Cod
ing
Test
ing
Cod
ede
liver
y
Fina
lrep
ortw
ritin
g
Insp
ectio
npr
epar
atio
n
Figure 7: Actual Project Timeline
Reg: 100051751 26
CMP-6013Y
5 Conclusion
5.1 Java is a poor choice of language for this project
Most of the other chess engines available for inspection online use the C/C++ pro-
gramming language. This is due to the fact that there is no-virtual machine used when
executing C-based code, and the fact that there is a major advantage to using smaller
integer sizes, such as bytes or shorts. This is shown in the figure 8 below from the Java
Virtual Machine Specification Tim Lindholm (2015).
Table from the Java VM Specification Tim Lindholm (2015) showing that when
loading values for calculations 32-bit words are the smallest load-in size.
Figure 8: Chessboard
5.2 Non-OO-programming difficulty
One of the main advantages of an object oriented system is th ability to easily trace an
error back to a particular line of code, however with linear-styled programming errors
are frequent and hard to detect. This is a major set-back when coding any project,
especially one that uses recursive methods to perform calculations as these errors can
be concealed within the execution stack. This made the coding of this project take
between four and ten times longer to get working correctly. This style of programming,
although efficient, is extremely outdated and should not be used in large scale projects,
especially in an OO-optimised language such as Java.
Reg: 100051751 27
CMP-6013Y
5.3 General
Although the project was completed before the deadline, the time taken to code the
project was greatly extended by plagues of errors and set-backs due to needing to con-
stantly alter values within a linear structure. This was a very challenging project to
complete and if repeated would be done very differently.
5.4 Future Work
This project can be easily extended to include a good UI, some examples of the elements
to be used in the UI are shown below in figure 9.
White Pawn White Rook White Knight White Bishop
White Queen White King Black Pawn Black Rook
Black Knight Black Bishop Black Queen Black King
Figure 9: UI Chess Pieces
Reg: 100051751 28
CMP-6013Y
6 Glossary
6.1 Chess Keywords
• Rank - A rank refers to the row that a piece occupies on the board, the ranks range
from one to eight, incrementing by one from the white-starting side of the board
towards the black-starting side of the board
• File - A file refers to the column that a piece occupies on the board, the files
range from A to H, incrementing alphabetically by one letter. The A file would be
located on the left side of the board (if viewing from the white-starting side of the
board), or the right hand side of the board (if viewing the board from the black-
starting side). (See starting positions for why this is important to get correct)
• Square - (see tile)
• Piece - a piece refers to any Pawn, Rook, Knight, Bishop, Queen or King markers
on the board, any single piece has a type and colour the symbols are defined in
the figure 10 below.
• Tile - a tile refers to one of the 64 black or white squares that make up a chess
board
• Board - the board refers to the eight by eight arrangement of black and white
alternating tiles that make up the field of play. The tiles should start with the
square A1 being black and alternating horizontally and vertically from there. A
typical chess game should have this board with a setup of 32 pieces (16 black and
16 white) on it (See starting positions for more information) The board uses the
rank and file system starting with A1 which is occupied by a white rook at the
start of the game (see figure 11 below)
• Legal Move - refers to any new position that a piece can move to on the board that
is allowed by both the moves of the piece type and the rules of the board.
• Move - a full move is when both black and white have performed a legal move
during their turns
Reg: 100051751 29
CMP-6013Y
Examples of all Chess Pieces 84th FIDE Congress (2014)
Figure 10: List of Chess Pieces
• Moves of a piece - refers to all of the possible legal-moves, specific to each piece
type/state (e.g. 2x1 in any direction by knight)
• Starting positions - the standard starting layout of a chess game starts with white
pawns along the second rank on every file, Rooks on in the end rank in the corners,
followed by Knights on either side, followed by bishops on either side, followed
by a King on the E File and a Queen on the D File. Seen in figure 12.
• Turn - refers to the player who is currently able to make a legal-move, if no legal-
move is available, depending upon check may force stalemate or checkmate.
• Black / White - refers to the two players of the chess game, although white and
black may not actually be the colours of the pieces the roles stay the same. White
always has the first turn.
• Check - if a player’s king is able to be attacked on the opponents next turn by one
or more of their pieces, then the player is referred to as being in check.
Reg: 100051751 30
CMP-6013Y
Figure 11: Chessboard
• Checkmate - when a player is in check and there are no legal moves for them to
make then that player is considered to be in checkmate and the opponent wins.
• Stalemate - when a player is not in check and there are no legal moves available
to the player, stalemate is called and the game is a draw.
• Three-fold repetition - If the same positions are repeated 3 times within a game
then a draw may be called by either player on their turn. 84th FIDE Congress
(2014)
• Fifty move rule - if after 50 full moves no pieces have been captured or no pawn
has been moved, a draw may be called 84th FIDE Congress (2014)
• En’ Passant Capture - refers to a special capture case where (for white capturing
black) a pawn that is located on the fifth rank can capture another pawn that is
directly to the left or right of it by moving diagonally forward to the side of the
enemy pawn. This can only occur immediately after the enemy pawn has moved
forward two tiles from its starting position. The figure below shows the pawn
moving forward two to the fifth rank, and then the white pawn on the fifth rank
moving diagonally forward-right to take the black pawn via En Passant Capture.
This is shown in figure 13.
Reg: 100051751 31
CMP-6013Y
This figure shows the starting positions for the chessboard 84th FIDE Congress
(2014)
Figure 12: Starting Board
• Castle - refers to a special move between an unmoved king and an unmoved rook
piece, either on the king-side files of the board or the queen-side files of the board
(see figure 14 below)
• Promote - refers to when a pawn reaches the opposite end of the board, and it can
be promoted to any non-king and non-pawn piece.
Reg: 100051751 32
CMP-6013Y
Examples of En Passant Capture 84th FIDE Congress (2014)
Figure 13: En Passant
6.2 Programming Terms
• Tables - An array of values that act as an overlay for the board that implies a
certain value for a certain position on the board. The exact table used would be
determined by the type and colour of the piece that is being evaluated.
• Starting Index - the value that an array starts counting from (usually zero)
• IF Statement - The if statement allows conditional execution of a statement or
a conditional choice of two statements, executing one or the other but not both
James Gosling (2015)
• Switch Statement - The switch statement transfers control to one of several state-
ments depending on the value of an expression James Gosling (2015)
• Class - A Class object exists for each reference type. It can be used, for exam-
ple, to discover the fully qualified name of a class, its members, its immediate
superclass, and any interfaces that it implements. James Gosling (2015)
• Static - If a field is declared static, there exists exactly one incarnation of the
field, no matter how many instances (possibly zero) of the class may eventually
be created
Reg: 100051751 33
CMP-6013Y
Examples of Castling on both Black and White
Figure 14: Castling
• Bit - an individual binary one or zero
• Byte - from -128 to 127, inclusive James Gosling (2015)
• Short - from -32768 to 32767, inclusive James Gosling (2015)
• Integer - from -2147483648 to 2147483647, inclusive James Gosling (2015)
• Word - a group of 32 bits
• User Interface (UI) - A means of a user being able to interact with the program at
run-time
• Object Oriented (OO) Programming - Using classes to try and model problems
and structures as objects with properties that can interact with each other
• Linear Programming - A simple programming style where code is executed with
no attempt to model the problem, simply executing code from the top of the
method to the bottom.
• Recursion - A method that calls itself to stack the computations level by level
Reg: 100051751 34
CMP-6013Y
References
84th FIDE Congress, T. (2014). Laws of chess: For competitions starting on or after 1
july 2014.
James Gosling, Bill Joy, G. S. G. B. A. B. (2015). The javaÂo language specification(8th
ed.).
Soltis, A. E. (2002). Chess: The time element and competition. EncyclopÃedia Britan-
nica.
Stuart J Russell, P. N. (1995). Artificial intelligence. Prentice Hall.
Tim Lindholm, Frank Yellin, G. B. A. B. (2015). The javaÂo virtual machine specifica-
tion(8th ed.).
Reg: 100051751 35