Reputation: 31
I'm making a simple chess game for fun and to learn better code architecture, but I'm stuck on a design choice. For simplicity I have 3 classes
Requirements:
I initially stored reference in Tile class to Piece and a reference in Piece to Tile. This worked, but I got concerned that this could lead to buggy code where something falls out of sync. For example, somewhere in the codebase I would update the Piece.tile reference, but forget to update the Tile.piece reference.
My question is: Is my current design poor or am I overthinking it? Is there a better approach here? Should I try to enforce a single source of truth here?
Here is my move function.
public void Move(Tile fromTile, Tile toTile, Piece p){
if (toTile.HasOccupant){
throw new Exception("Tile should be empty before moving a piece to it");
}
p.Move(fromTile, toTile);
fromTile.UnsetOccupant();
toTile.SetOccupant(p);
}
Upvotes: 0
Views: 36
Reputation: 78
I think enforcing a single source of truth is the way to go here. You can centralize the game state in a Grid
(or Board
) class and get rid of the Tile
class altogether, as its only functionality is storing its occupancy status, which can be done using a simple 2D array. This eliminates any circular dependencies between classes/instances and thus potential out of sync issues.
Here's an example implementation:
public class Grid {
private final static int SIZE = 8;
private Piece[][] board = new Piece[SIZE][SIZE];
public Piece getPieceAt(int row, int col) {
return board[row][col];
}
public void movePiece(int fromRow, int fromCol, int toRow, int toCol) {
if (board[toRow][toCol] != null) {
throw new Exception("Tile should be empty before moving a piece to it");
}
Piece piece = board[fromRow][fromCol];
if (piece == null) {
throw new Exception("No piece at the source tile");
}
board[toRow][toCol] = piece;
board[fromRow][fromCol] = null;
piece.setPosition(toRow, toCol);
}
}
Upvotes: 0