Blob Blame Raw
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormPaint(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

const
  rows = 20;
  cols = 30;
  size = 20;
var
  Form1: TForm1;
  field1, field2: array [0..cols, 0..rows] of boolean;

implementation

{$R *.lfm}

function getCell(x, y: integer): integer;
begin
  Result := 0;
  x := (x + cols) mod cols;
  y := (y + rows) mod rows;
  if field1[x, y] then Result := 1;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  i, j: integer;
begin
  Canvas.Brush.Color := clBlack;
  for i := 0 to cols-1 do begin
    for j := 0 to rows-1 do begin
      Canvas.MoveTo(i*size, (j+1)*size);
      Canvas.LineTo((i+1)*size, (j+1)*size);
      Canvas.LineTo((i+1)*size, j*size);
      if field1[i, j] then Canvas.Ellipse(i*size, j*size, (i+1)*size, (j+1)*size);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := not Timer1.Enabled;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i, j, count: integer;
begin
  for i := 0 to cols-1 do begin
    for j := 0 to rows-1 do begin
      count := 0;
      count := count + getCell(i-1, j-1);
      count := count + getCell(i-1, j);
      count := count + getCell(i-1, j+1);
      count := count + getCell(i, j-1);
      count := count + getCell(i, j+1);
      count := count + getCell(i+1, j-1);
      count := count + getCell(i+1, j);
      count := count + getCell(i+1, j+1);
      if field1[i, j] then begin
        field2[i, j] := (count=2) or (count=3);
      end else begin
        field2[i, j] := count=3;
      end;
    end;
  end;
  field1 := field2;
  Refresh;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  i, j: integer;
begin
  i := x div size;
  j := y div size;
  if (i < cols) and (j < rows) then field1[i, j] := not field1[i, j];
  refresh;
end;

end.