This package implements a classic graphical chessgame using a public domain chesspiece icon set. It implements the MiniMax chess-playing algorithm, with Alpha/Beta pruning to narrow the decision tree.
The game UI includes a scrolling textarea to the right of the board. The game records each move made to the textarea in algebraic notation. In addition, if the player makes any error in play (such as attempting a move that would put their King in check), a temporary error message is printed there.
The project comes to 2,816sloc of Java 17. Further implementation details below. Some screencaps:
JChessGame
Source: GitHub Repository
Implementation Details
The initial implementation of the chessboard logic, in a naive OO style, lead to incredibly slow performance of the MiniMax algorithm— over a minute per move. I threw that code out; betting that javac could optimize primitives-based code, I reimplemented the chessboard logic in BoardArrays.java using nothing but integers and integer arrays. Indeed, this brought the alogrithm’s runtime down to less than 0.5sec— a 1800% improvement. I’ll remember that next time I need to optimize an algorithm in Java!
BoardArrays.java
A static class offering a selection of utility methods for manipulating the titular ‘board arrays’.
In the code, a board array is an 8 × 8 integer array-of-arrays that represents a chessboard. Chesspieces are represented using integer codes that are composited from integer flags.
For example, a white pawn would be represented by 260 = WHITE | PAWN
, where WHITE (256)
and PAWN (4)
are both integer flags defined at the top of the class. In another example, the black queen would be 576 = BLACK | QUEEN, from BLACK (512)
and QUEEN (64)
.
MinimaxRunner.java
A class that encapsulates the MiniMax algorithm, featuring the frontend at algorithmTopLevel()
. The lower calls are executed by algorithmLowerLevel()
.
Crucially, this class also implements evaluateBoard()
and its dependent methods. The MiniMax algorithm on its own isn’t enough to effect a chess AI; the algorithm depends on being able to interpolate a given chess position into a number representing how advantageous that position is to the AI.
I implemented the evaluation algorithm originally penned by Claude Shannon in his 1949 paper Programming a Computer for Playing Chess. (I don’t pretend to have read this paper.)
BoardView.java
A subclass of JComponent that implements the chessboard display in particular. The board’s black-and-beige design is not an image; it is constructed to scale using Graphics.fillRect()
.
All the logic pertaining to the player’s move is packed into BoardView.mouseClicked()
, 174sloc in total. I break the logic up into 4 subordinate methods for readability.
In order to partition the AI’s move logic, I wrote the class to implement the ActionListener
interface. At the end of mouseClicked()
a timer is triggered, which calls actionPerformed()
.
I leverage the control flow separation if a pawn promotion dialog needs to execute at the end of the player’s move; actionPerformed()
defers until the promotion is complete.
Chessboard.java
This class manages the chessboard state of the game; it’s used by BoardView to track the board, and it itself uses methods from BoardArrays
to do the internals work.
(Of note: As a static class, BoardArrays
doesn’t instance an object and can’t track state. Chessboard
encapsulates the actual board array in its state and provides implementation-friendly methods for managing it.)
This class offers gameplay-specific methods like isMovePossible()
, isCastlingPossible()
, and movePieceCastling()
.