0

I am creating a game using delphi and want to move some of my code to a separate unit, however this code uses attributes from a form. Is this possible?

I am creating a game using a VCL form application and currently have all my code for the game algorithm in form unit. There is nothing wrong with this, as in my program runs well, except it looks messy and I have been advised to put the algorithm code in a separate unit. I have tried moving the code into a new unit, however whatever I try syntax errors appear.

This is code in my main unit where Grid is TStringGrid from the form and GridSize is a procedure from my attempted second unit:

procedure TGame.NewGame;
begin
  Grid.Width:=GridSize(Grid.ColCount);
  Grid.Height:=GridSize(Grid.RowCount);
end;

This is the second unit code:

unit UGameGenerator;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.Menus, 
  Vcl.StdCtrls;

implementation

function GridSize(size: integer): integer;
begin
  result:=291+36*(size-8);
end;

end.

EDIT:

This is code from the second unit:

procedure ClearGrid;
var
  i,j: integer;
begin
  for i := 0 to Grid.ColCount-1 do
  begin
    for j := 0 to Grid.RowCount-1 do
    begin
      Grid.Cells[i,j]:='';
    end;
  end;
end;
Ken White
  • 123,280
  • 14
  • 225
  • 444
Elsie.J
  • 9
  • 2

1 Answers1

2

The compiler needs to find the declaration of GridSize somehow. To do that, follow this guide:

  1. In the main form, add UGameGenerator to the uses list:

    unit MainForm;
    
    interface
    
    uses
      ...,UGameGenerator; // Add here or in the implementation section
    
    ...
    implementation
    
    ...
    
    end.
    
  2. In your UGameGenerator unit, expose all types/functions/procedures that is used in other program parts in the interface:

    unit UGameGenerator;  
    
    interface
    
    uses
      ...,...;
    
    function GridSize(size: integer): integer;  
    
    implementation
    
    function GridSize(size: integer): integer;
    begin
      result:=291+36*(size-8);
    end;        
    
    end.
    

A tip when designing the separate unit, avoid using variables directly from other units. Instead pass them as parameters in procedure/function calls.

Otherwise you risk to have much trouble with circular references.

In your updated question, declare procedure ClearGrid( aGrid : TStringGrid); and pass the grid as a parameter.

LU RD
  • 34,438
  • 5
  • 88
  • 296
  • Thank you so much. I had forgotten to add the function to the interface. I have added some more code to the question which I'm struggling with. Any chance you could help? – Elsie.J Jan 21 '19 at 23:06
  • Separating the GUI from program logic is one of the most important things a programmer will have to learn. I updated the answer with a hint how to get started. Be prepared to invest some effort to master that part. It will pay in the end. – LU RD Jan 21 '19 at 23:20
  • Okay. Thank you so much – Elsie.J Jan 22 '19 at 08:01