zdani
zdani

Reputation: 31

How to avoid circular dependencies in my chess project?

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

Answers (1)

adammak
adammak

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

Related Questions