35
Registration number 100051751 2016 Constructing a Chess Engine in the Java Programming Language Supervised by Gavin Cawley University of East Anglia Faculty of Science School of Computing Sciences

Constructing a Chess Engine in the Java Programming Language

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Constructing a Chess Engine in the Java Programming Language

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

Page 2: Constructing a Chess Engine in the Java Programming Language

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.

Page 3: Constructing a Chess Engine in the Java Programming Language

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

Page 4: Constructing a Chess Engine in the Java Programming Language

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

Page 5: Constructing a Chess Engine in the Java Programming Language

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

Page 6: Constructing a Chess Engine in the Java Programming Language

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

Page 7: Constructing a Chess Engine in the Java Programming Language

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

Page 8: Constructing a Chess Engine in the Java Programming Language

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

Page 9: Constructing a Chess Engine in the Java Programming Language

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

Page 10: Constructing a Chess Engine in the Java Programming Language

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

Page 11: Constructing a Chess Engine in the Java Programming Language

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

Page 12: Constructing a Chess Engine in the Java Programming Language

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

Page 13: Constructing a Chess Engine in the Java Programming Language

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

Page 14: Constructing a Chess Engine in the Java Programming Language

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

Page 15: Constructing a Chess Engine in the Java Programming Language

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

Page 16: Constructing a Chess Engine in the Java Programming Language

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

Page 17: Constructing a Chess Engine in the Java Programming Language

CMP-6013Y

This figure shows the border values of the diagonal edges of the board

Figure 2: Diagonal Edges

Reg: 100051751 17

Page 18: Constructing a Chess Engine in the Java Programming Language

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

Page 19: Constructing a Chess Engine in the Java Programming Language

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

Page 20: Constructing a Chess Engine in the Java Programming Language

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

Page 21: Constructing a Chess Engine in the Java Programming Language

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

Page 22: Constructing a Chess Engine in the Java Programming Language

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

Page 23: Constructing a Chess Engine in the Java Programming Language

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

Page 24: Constructing a Chess Engine in the Java Programming Language

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

Page 25: Constructing a Chess Engine in the Java Programming Language

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

Page 26: Constructing a Chess Engine in the Java Programming Language

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

Page 27: Constructing a Chess Engine in the Java Programming Language

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

Page 28: Constructing a Chess Engine in the Java Programming Language

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

Page 29: Constructing a Chess Engine in the Java Programming Language

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

Page 30: Constructing a Chess Engine in the Java Programming Language

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

Page 31: Constructing a Chess Engine in the Java Programming Language

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

Page 32: Constructing a Chess Engine in the Java Programming Language

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

Page 33: Constructing a Chess Engine in the Java Programming Language

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

Page 34: Constructing a Chess Engine in the Java Programming Language

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

Page 35: Constructing a Chess Engine in the Java Programming Language

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