A complete chess implementation in Java with a Swing interface, user accounts, saved games, move validation for every piece, check and checkmate detection, draw by repetition, a live move log, and a scoring system.
The project was built in two stages: first as a console application with the game logic and JSON persistence, then refactored into packages and rebuilt around a graphical interface and four design patterns. This repository holds the final version.
chess/
├── core/ Game, Board, Player, Move, Position, Colors, GameResult
│ └── exceptions/
├── pieces/ Piece, ChessPiece, and the six concrete pieces
├── strategies/ MoveStrategy and ScoreStrategy implementations
├── observers/ GameObserver, GameSubject, Logger, ScoreManager
├── data/ ParsedData (JSON I/O), PieceFactory, User
└── ui/ Swing screens — login, menus, board, game info
The package split follows responsibility rather than class type: game rules in
core, movement algorithms in strategies, everything that reacts to a move in
observers, and the interface entirely in ui. No core class imports from
ui, so the game logic would run unchanged behind a different front end, which
is precisely what happened between the two stages of the project.
Each piece delegates its movement to a MoveStrategy implementation rather than
computing legal squares itself. RookMoveStrategy, BishopMoveStrategy,
KnightMoveStrategy and the rest each answer one question: given a board and a
starting square, which squares can be reached?
Pawns are the reason this pays off. They move in opposite directions depending on
colour, so WhitePawnMoveStrategy and BlackPawnMoveStrategy are separate
implementations of the same interface, no colour flag threaded through the
movement code, no sign flips scattered around.
The same pattern handles scoring: ScoreStrategy declares how many points a
capture and a game result are worth, and CalculateChessScore implements the
standard values, 90 for a queen, 50 for a rook, 30 for a bishop or knight, 10
for a pawn, ±300 for a win or loss, ±150 for a resignation. Swapping in a
different scoring system means writing one class.
Game implements GameSubject and notifies its observers on three events: a
move made, a piece captured, and a turn switch. Two observers listen:
Loggerappends the move to the on-screen log and updates the captured piece icons.ScoreManageraccumulates points for captures and applies the final score to the user's account when the game ends.
Without this, Game would need direct references to the interface components,
and the game logic would stop compiling the moment the UI changed. Instead it
knows only that something is listening.
PieceFactory centralises piece construction across three different situations:
loading a saved game from JSON, setting up a new board, and promoting a pawn.
Each needs a piece built from slightly different information, but none of them
needs to know about the concrete classes.
Main has a private constructor and a static getInstance(), so a single
instance holds the user list, the loaded games and the current session. Every
screen reaches the same state through it, without passing a context object down
through the whole interface.
Accounts. Registration and login, with credentials and accumulated points
stored in accounts.json. Registering an existing email raises
AccountAlreadyExsists; wrong credentials raise InvalidDataException.
Saved games. Games are read from games.json, so a player can resume a
position rather than always starting fresh. The board state, move history and
players are all reconstructed on load.
Rules. Legal move generation for all six piece types, capture handling, pawn promotion, check and checkmate detection, and draw by repetition.
Interface. Swing screens for login, registration, the main menu, colour selection, the saved game list, the board itself, and a final results page. The board shows the move log and the captured pieces alongside it.
The only dependency is json-simple, included in lib/.
javac -cp lib/json-simple-1.1.1.jar -d out $(find src -name "*.java")
java -cp out:lib/json-simple-1.1.1.jar chess.MainOn Windows, use ; instead of : as the classpath separator.
The program reads input/accounts.json and input/games.json and loads the
piece images from input/whitePieces and input/blackPieces, so run it from the
project root.
The account credentials in input/accounts.json are sample data used for
testing the login flow, they are not real accounts.