How to avoid circular unit reference?

circular-reference, delphi, project-organization

Solution

Change the unit that defines TChessPiece to look like the following:

TYPE
  tBaseChessBoard = class;

  TChessPiece = class
    procedure GetMoveTargets (BoardPos : TPoint; Board : TBaseChessBoard; ...    
  ...
  end;    

then modify the unit that defines TChessBoard to look like the following:

USES
  unit_containing_tBaseChessboard;

TYPE
  TChessBoard = class(tBaseChessBoard)
  private
    FBoard : array [1..8, 1..8] of TChessPiece;
  ...
  end;  

This allows you to pass concrete instances to the chess piece without having to worry about a circular reference. Since the board uses the Tchesspieces in its private, it really doesn't have to exist prior to the Tchesspiece declaration, just as place holder. Any state variables which the tChessPiece must know about of course should be placed in the tBaseChessBoard, where they will be available to both.

Problem

Imagine the following two classes of a chess game: ``` TChessBoard = class private FBoard : array [1..8, 1..8] of TChessPiece; ... end; TChessPiece = class abstract public procedure GetMoveTargets (BoardPos : TPoint; Board : TChessBoard; MoveTargetList : TList <TPoint>); ... end; ``` I want the two classes to be defined in two separate units ChessBoard.pas and ChessPiece.pas. How can I avoid the circular unit reference that I run into here (each unit is needed in the other unit's interface section)?

Original source