-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGameOfLife.pas
150 lines (132 loc) · 4.12 KB
/
GameOfLife.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
unit GameOfLife;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ExtCtrls, GameOfLifeUtils,
Vcl.ComCtrls, Vcl.StdCtrls, Vcl.Samples.Spin, Math;
type
TMainForm = class(TForm)
MainGrid: TDrawGrid;
StatusBar1: TStatusBar;
PeriodTimer: TTimer;
ButtonPanel: TPanel;
StartButton: TButton;
PauseButton: TButton;
TimeDurationSpinEdit: TSpinEdit;
PeriodLabel: TLabel;
RandomiseButton: TButton;
ClearButton: TButton;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure MainGridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
procedure PeriodTimerTimer(Sender: TObject);
procedure StartButtonClick(Sender: TObject);
procedure PauseButtonClick(Sender: TObject);
procedure RandomiseButtonClick(Sender: TObject);
procedure MainGridSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
procedure ClearButtonClick(Sender: TObject);
private
CurrentTimeValue: Integer;
{ Private declarations }
public
Cells: TAutomataCellArray;
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TMainForm.ClearButtonClick(Sender: TObject);
begin
TGameOfLifeUtils.GenocideCells(MainGrid, Cells);
MainGrid.Canvas.Refresh;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
TGameOfLifeUtils.ResizeGrid(MainForm, MainGrid);
TGameOfLifeUtils.PopulateCellArray(MainGrid, Cells);
TGameOfLifeUtils.RandomiseCells(MainGrid, Cells);
PeriodTimer.Interval := TimeDurationSpinEdit.Value;
end;
procedure TMainForm.FormResize(Sender: TObject);
var
TimerState: Boolean;
begin
TimerState := PeriodTimer.Enabled;
PeriodTimer.Enabled := False;
TGameOfLifeUtils.ResizeGrid(MainForm, MainGrid);
TGameOfLifeUtils.PopulateCellArray(MainGrid, Cells);
PeriodTimer.Enabled := TimerState;
end;
procedure TMainForm.MainGridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
var
BrushColor: TColor;
begin
if Cells[ARow, ACol].IsAlive then
BrushColor := clBlack
else
BrushColor := clWhite;
MainGrid.Canvas.Brush.Color := BrushColor;
MainGrid.Canvas.FillRect(Rect);
end;
procedure TMainForm.MainGridSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
var
BrushColor: TColor;
begin
case Cells[ARow, ACol].IsAlive of
True:
begin
Cells[ARow, ACol].IsAlive := False;
BrushColor := clWhite;
end;
False:
begin
Cells[ARow, ACol].IsAlive := True;
BrushColor := clBlack;
end;
end;
MainGrid.Canvas.Brush.Color := BrushColor;
MainGrid.Canvas.FillRect(MainGrid.CellRect(ACol, ARow));
MainGrid.Repaint;
end;
procedure TMainForm.PauseButtonClick(Sender: TObject);
begin
PeriodTimer.Enabled := False;
end;
procedure TMainForm.RandomiseButtonClick(Sender: TObject);
begin
TGameOfLifeUtils.RandomiseCells(MainGrid, Cells);
MainGrid.Repaint;
end;
procedure TMainForm.StartButtonClick(Sender: TObject);
begin
PeriodTimer.Enabled := True;
end;
procedure TMainForm.PeriodTimerTimer(Sender: TObject);
var
Row, Col, AliveCount, DeadCount, TotalCount: Integer;
CellIsAlive: Boolean;
CellArrayCopy: TAutomataCellArray;
begin
PeriodTimer.Interval := Max(1, TimeDurationSpinEdit.Value);
AliveCount := 0;
DeadCount := 0;
TotalCount := MainGrid.RowCount * MainGrid.ColCount;
CellArrayCopy := Copy(MainForm.Cells);
for Row := 0 to MainGrid.RowCount - 1 do
begin
CellArrayCopy[Row] := Copy(MainForm.Cells[Row]);
for Col := 0 to MainGrid.ColCount - 1 do
begin
CellIsAlive := TGameOfLifeUtils.IsAliveNextStep(MainGrid, CellArrayCopy, Row, Col);
MainForm.Cells[Row, Col].IsAlive := CellIsAlive;
if CellIsAlive then
AliveCount := AliveCount + 1;
end;
end;
DeadCount := TotalCount - AliveCount;
StatusBar1.SimpleText := Format('Alive: %d Dead: %d Columns: %d Rows: %d (%d cells)',
[AliveCount, DeadCount, MainGrid.ColCount, MainGrid.RowCount, TotalCount]);
MainGrid.Repaint;
end;
end.