New Life Game

 

A Manfred EigenRuthil Winkler: A játék című, 1981-ben kiadott könyvnek a 140-141. oldalain a Stanislaw Ulman-féle reprodukciós játék első 11 illetve a 45. fázisát láthatjuk. A képeken egyetlen egyedből kiindulva, egy folyamatosan növekvő szimmetrikus minták sorozatát kapjuk. Az életfázisok változási szabálya:

 

- Születés: ha egy hely négy lapszomszédjában összesen csak egy golyó található, akkor ott golyó jön létre.

- Kihalás: minden generáció csak kétgenerációnyi életet él, amikor 3. generációs lenne, akkorra kihal.

 

Legnagyobb igyekezetem ellenére, a 45. generáció képét előállítani nem tudtam. Hogy algoritmusom nem teljesen idegen a szabálytól, azt az is bizonyítja, hogy a 11. generációig hibátlanul működik. Nem értem, hogy miért nem jön létre az tankönyvi ábra szerinti 45. generáció. Ha valaki segítene benne, megköszönném.

 

         A 8. generáció:

 

 

         A 11. generáció:

 

 

         A 45. generáció:

 

 

         A program listája:

 

unit UNewLifeGame;

interface

uses
  Windows, MessagesSysUtilsClasses,

  GraphicsControlsFormsDialogsStdCtrlsExtCtrls, Spin;

type
  TfmNewLifeGame = class(TForm)
    btKilepesTButton;
    btStartTButton;
    lbEgyedTLabel;
    edEgyedSzTEdit;
    lbAktualSzTLabel;
    lbLepesSzTLabel;
    btKezdetTButton;
    btKovetkezoTButton;
    seSebessTSpinEdit;
    lbIdoTLabel;
    btStopTButton;
    btTorlesTButton;
    tiIdozitoTTimer;
    lbXTLabel;
    lbYTLabel;
    Procedure Start;
    Procedure Kepre;
    Procedure Ciklus;
    procedure btKilepesClick(SenderTObject);
    procedure btStartClick(SenderTObject);
    procedure btKezdetClick(SenderTObject);
    procedure btKovetkezoClick(SenderTObject);
    procedure btStopClick(SenderTObject);
    procedure seSebessChange(SenderTObject);
    procedure btTorlesClick(SenderTObject);
    procedure tiIdozitoTimer(SenderTObject);
    procedure FormMouseMove(SenderTObjectShiftTShiftState; X,
      Y: Integer);
    procedure FormPaint(SenderTObject);
    procedure FormCreate(SenderTObject);
    procedure FormDblClick(SenderTObject);
  private
    Private declarations }
  public
    Public declarations }
  end;

Const Max=95;
      D=8;
      Dx=4;
      Dy=4;
      Bal=150;
      Fent=3;
      R=3;
      FigyH=10;

var
  fmNewLifeGameTfmNewLifeGame;
  EtGeSzArray[0..Max,0..Max] Of Byte;
  MxMy: Integer;
  EgyedSzLepesSzAktualSz: Word;
  EggyesLepo, Folyamatos, VegFigyeloBoolean;
  FigyTombArray[1..FigyH] Of Word;

implementation

{$R *.DFM}

procedure TfmNewLifeGame.Start;
Var I, J, M, N: Word;
Begin
  RandomizeEgyedSz:= StrToInt(edEgyedSz.Text); LepesSz:= 1;
  If EgyedSz>Max*Max Then EgyedSz:= Max*Max;
  edEgyedSz.Text:= IntToStr(EgyedSz);
  lbAktualSz.Caption:= IntToStr(EgyedSz);
  lbLepesSz.Caption:= IntToStr(LepesSz);
  For I:= 0 To Max Do For J:= 0 To Max Do Et[I,J]:= 0; Sz:= Et;
  For I:= 1 To EgyedSz Do
  Begin
    Repeat
      M:= Random(Max+1);
      N:= Random(Max+1);
    Until Et[M,N]=0;
    Et[M,N]:= 1;
  End;
  For I:= 1 To FigyH Do FigyTomb[I]:= 0;
End;

procedure TfmNewLifeGame.Kepre;
Var I, J: Word;
Begin
  With Canvas Do
  Begin
    Pen.Color:= clBtnFace;
    Brush.Color:= clBtnFaceRectangle(Bal-R,Fent-R,980,800);
    Pen.Color:= clBlueBrush.Color:= clBlue;
    For I:= 0 To Max Do For J:= 0 To Max Do If Et[I,J]=0 Then
    Pixels[Bal+D*I,Fent+D*J]:= clBlue Else
    Ellipse(Bal+D*I-R,Fent+D*J-R, Bal+D*I+R,Fent+D*J+R)
  End;
End;

Procedure TfmNewLifeGame.Ciklus;
Var I, J, SS: Word;
Begin
  For I:= 0 To Max Do For J:= 0 To Max Do Sz[I,J]:= 0;
  For I:= 1 To Max-1 Do For J:= 1 To Max-1 Do
  Begin
    SS:= 0;
                If Et[I-1,J]<>0 Then Inc(SS);
    If Et[I,J-1]<>0 Then Inc(SS); If Et[I,J+1]<>0 Then Inc(SS);
                If Et[I+1,J]<>0 Then Inc(SS);

    If (Et[I,J]=0) And (SS=1) Then Sz[I,J]:= 1; //születik
  End;
  For I:= 0 To Max Do For J:= 0 To Max Do
  If Et[I,J]<>0 Then Sz[I,J]:= Et[I,J]+1;      //ha él öregszik

  For I:= 0 To Max Do For J:= 0 To Max Do
  If Sz[I,J]>2 Then Sz[I,J]:= 0;                //ha túlságosan öreg, kihal
  Et:= Sz;
End;

procedure TfmNewLifeGame.btKilepesClick(SenderTObject);
begin
  Close;
end;

procedure TfmNewLifeGame.btStartClick(SenderTObject);
begin
  Folyamatos:= True;
end;

procedure TfmNewLifeGame.btKezdetClick(SenderTObject);
begin
  Start;
  Kepre;
end;

procedure TfmNewLifeGame.btKovetkezoClick(SenderTObject);
Var I, J, N: Word;
begin
  Inc(LepesSz); lbLepesSz.Caption:= IntToStr(LepesSz); Ciklus;
  With Canvas Do
  Begin
    N:= 0;
    Pen.Color:= clBtnFace;
    Brush.Color:= clBtnFaceRectangle(Bal-R,Fent-R,900,800);
    For I:= 0 To Max Do For J:= 0 To Max Do
    Case Et[I,J] Of
      0: Begin
           Pixels[Bal+D*I,Fent+D*J]:= clBlue;
         End;
      1: Begin
           Pen.Color:= clBlueBrush.Color:= clBlue;
           Ellipse(Bal+D*I-R,Fent+D*J-R, Bal+D*I+R,Fent+D*J+R);
           Inc(N);
         End;
      2: Begin
           Pen.Color:= clRedBrush.Color:= clRed;
           Ellipse(Bal+D*I-R,Fent+D*J-R, Bal+D*I+R,Fent+D*J+R);
           Inc(N);
         End;
    End;
  End;
  lbAktualSz.Caption:= IntToStr(N);
end;

procedure TfmNewLifeGame.btStopClick(SenderTObject);
begin
  Folyamatos:= False;
end;

procedure TfmNewLifeGame.seSebessChange(SenderTObject);
begin
  tiIdozito.Interval:= StrToInt(seSebess.Text);
end;

procedure TfmNewLifeGame.btTorlesClick(SenderTObject);
Var I,J: Word;
begin
  For I:= 0 To Max Do For J:= 0 To Max Do Et[I,J]:= 0; Sz:= Et;
  LepesSz:= 0; AktualSz:= 0;
  KeprelbAktualSz.Caption:= IntToStr(AktualSz);
end;

procedure TfmNewLifeGame.tiIdozitoTimer(SenderTObject);
begin
  If Not Folyamatos Then Exit;
  btKovetkezoClick(Sender);
end;

procedure TfmNewLifeGame.FormMouseMove(SenderTObjectShiftTShiftState;
  X, Y: Integer);
begin
  Mx:= X;
  My:= Y;
  If ((Mx-Bal+DxDiv D) In [0..Max] Then
  lbX.Caption:= IntToStr((Mx-Bal+DxDiv D);
  If ((My-Fent+DyDiv D) In [0..Max] Then
  lbY.Caption:= IntToStr((My-Fent+DyDiv D);
end;

procedure TfmNewLifeGame.FormPaint(SenderTObject);
begin
  Kepre;
end;

procedure TfmNewLifeGame.FormCreate(SenderTObject);
begin
  EgyedSz:= 0; AktualSz:= 0; LepesSz:= 1;
  edEgyedSz.Text:= IntToStr(EgyedSz);
  lbLepesSz.Caption:= IntToStr(LepesSz);
  lbAktualSz.Caption:= IntToStr(AktualSz);
  Eggyeslepo:= True;
  Folyamatos:= False;
end;

procedure TfmNewLifeGame.FormDblClick(SenderTObject);
Var I, J: Word;
begin
  edEgyedSz.Text:= '1'; AktualSz:= 0; LepesSz:= 1;
  Et[(Mx-Bal+DxDiv D,(My-Fent+DyDiv D]:=
  1 - Et[(Mx-Bal+DxDiv D,(My-Fent+DyDiv D];
  For I:= 0 To Max Do For J:= 0 To Max Do If Et[I,J]=1 Then Inc(AktualSz);
  KeprelbAktualSz.Caption:= IntToStr(AktualSz);
end;

end.