Einzelnen Beitrag anzeigen

BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Hilfe bei einer Simulation

  Alt 1. Jan 2009, 02:06
Hallo

Ich arbeite derzeit an einer kleinen Simulation, bei der ich gerade ein paar kleine Probleme habe. Ich stell euch am besten mal den Quellcode erstmal zur Verfügung. Bitte nicht gleich über mich schimpfen, ist einfach erstmal erstellt worden, ohne ihn so weit wie möglich zu verkürzen oder alles in Proceduren auszulagern.

Hier erstmal der Quellcode:

Delphi-Quellcode:

unit MainLeben;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    PaintBox1: TPaintBox;
    Timer1: TTimer;
    Button1: TButton;
    TreeView1: TTreeView;
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    Bmp: Tbitmap;
  public
    { Public-Deklarationen }
  end;

const LEb1AnfZahl = 5;
      Leb1Bew = 10;
      Leb1FortPflanzungsWasser = 200;
      Leb1FortPflanzungsNahrung = 200;
      Leb1NahrungOhneBewegung = 5;
      Leb1WasserOhneBewegung = 5;
      Leb1Schwanger = 3;

type TLebensform = record
  ix, iy, iNahrung, iWasser, iBewegung, iSchwanger: integer;
  bFortpflanzen: boolean;
end;

type TOrt = record
  iNahrung, iWasser, iSchwierigkeit: integer;
end;

var
  Form1: TForm1;
  Lebensform1: array of TLebensform;
  Welt: array of array of TOrt;

implementation

{$R *.dfm}
procedure TreeView_anpassen;
var i: integer;
begin
  Form1.TreeView1.Items.Clear;
  for i:= 0 to Length(Lebensform1)-1 do
    begin
      Form1.Treeview1.Items.Add(nil,'Lebensform ' + inttostr(i+1));
      Form1.Treeview1.Items.Add(nil,'X = ' + inttostr(Lebensform1[i].ix));
      Form1.Treeview1.Items.Add(nil,'Y = ' + inttostr(Lebensform1[i].iy));
      Form1.Treeview1.Items.Add(nil,'Nahrung = ' + inttostr(Lebensform1[i].iNahrung));
      Form1.Treeview1.Items.Add(nil,'Wasser = ' + inttostr(Lebensform1[i].iWasser));
    end;

  Form1.Treeview1.Items.Add(nil,'FeldWasser ' + inttostr(Welt[0,0].iWasser));
  Form1.Treeview1.Items.Add(nil,'FeldNahrung ' + inttostr(Welt[0,0].iNahrung));

end;

procedure Bildloeschen;
var i: integer;
begin
  Form1.Bmp.Canvas.Pen.Color := clWhite;
  for i := 0 to Length(Lebensform1)-1 do Form1.Bmp.Canvas.Rectangle(Lebensform1[i].ix-1,Lebensform1[i].iy-1,Lebensform1[i].ix+1,Lebensform1[i].iy+1);
  Form1.PaintBox1.Repaint;
end;

procedure Bildzeichnen;
var i: integer;
begin
  Form1.Bmp.Canvas.Pen.Color := clBlue;
  for i := 0 to Length(Lebensform1)-1 do Form1.Bmp.Canvas.Rectangle(Lebensform1[i].ix-1,Lebensform1[i].iy-1,Lebensform1[i].ix+1,Lebensform1[i].iy+1);
  Form1.PaintBox1.Repaint;
end;

procedure Weltinitialisieren;
var i, j: integer;
begin
  for i := 0 to 504 do
    begin
      for j := 0 to 496 do
        begin
          Welt[i,j].iNahrung := random(3);
          Welt[i,j].iWasser := random(3);
          Welt[i,j].iSchwierigkeit := random(3);
        end;
    end;
end;

procedure Weltzeichnen;
var i, j: integer;
begin
  for i := 0 to 504 do
    begin
      for j := 0 to 496 do
        begin
          if ((Welt[i,j].iNahrung + Welt[i,j].iWasser) < 20) then Form1.Bmp.Canvas.Pixels[i+1,j+1] := clgray;
          if ((Welt[i,j].iNahrung + Welt[i,j].iWasser) in [20..50]) then Form1.Bmp.Canvas.Pixels[i+1,j+1] := clYellow;
          if ((Welt[i,j].iNahrung + Welt[i,j].iWasser) > 50) then Form1.Bmp.Canvas.Pixels[i+1,j+1] := clgreen;
        end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Button1.Caption = 'Simulation startenthen
    begin
      Timer1.Enabled := true;
      Button1.Caption := 'Simulation stoppen';
    end
  else
    begin
      Timer1.Enabled := false;
      Button1.Caption := 'Simulation starten';
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
  Bmp := TBitmap.create;
  Bmp.Width := 505;
  Bmp.Height := 497;
  SetLength(Welt, Bmp.Width, Bmp.Height);
  randomize;
  SetLength(Lebensform1,1);
  for i := 0 to 0 do
    begin
      Lebensform1[i].ix := random(20)+1;
      Lebensform1[i].iy := random(20)+1;
      Lebensform1[i].iNahrung := 0;
      Lebensform1[i].iWasser := 0;
      Lebensform1[i].iSchwanger := 0;
      Lebensform1[i].iBewegung := Leb1Bew;
    end;
  Weltinitialisieren;
  Weltzeichnen;
  Bildzeichnen;
  TreeView_anpassen;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  BitBlt(Paintbox1.Canvas.Handle, 0, 0, Paintbox1.Width, Paintbox1.Height,
    Bmp.Canvas.Handle, 0, 0, SRCCOPY);
end;

procedure Bewegen(var Objekt: TLebensform);
var i: integer;
begin
  repeat
    case random(3) of
    0: Objekt.ix := Objekt.ix - 1;
    1: Objekt.ix := Objekt.ix;
    2: Objekt.ix := Objekt.ix + 1;
    end;
  until Objekt.ix > 1;

  repeat
    case random(3) of
    0: Objekt.iy := Objekt.iy - 1;
    1: Objekt.iy := Objekt.iy;
    2: Objekt.iy := Objekt.iy + 1;
    end;
  until Objekt.iy > 1;
end;

procedure Feld_ueberpruefen(Var Objekt: TLebensform);
begin
  if (Welt[Objekt.ix-1,Objekt.iy-1].iNahrung > 0) and (Objekt.iBewegung >0) then
    begin
      Objekt.iNahrung := Objekt.iNahrung + Welt[Objekt.ix-1,Objekt.iy-1].iNahrung;
      Welt[Objekt.ix-1,Objekt.iy-1].iNahrung := 0;
      Objekt.iBewegung := Objekt.iBewegung -1;
    end;
  if (Welt[Objekt.ix-1,Objekt.iy-1].iWasser > 0) and (Objekt.iBewegung >0) then
    begin
      Objekt.iWasser := Objekt.iWasser + Welt[Objekt.ix-1,Objekt.iy-1].iWasser;
      Welt[Objekt.ix-1,Objekt.iy-1].iWasser := 0;
      Objekt.iBewegung := Objekt.iBewegung -1;
    end;
end;

procedure Lebensform_versetzen;
var i, iIndex, iIndey, iIndez: integer;
    LebenTemp: array of TLebensform;
begin
  for i := 0 to Length(Lebensform1)-1 do
    begin
      Lebensform1[i].iBewegung := Leb1Bew;
      if (Lebensform1[i].iNahrung > (Leb1FortPflanzungsNahrung + (3*Leb1NahrungOhneBewegung))) and
         (Lebensform1[i].iWasser > (Leb1FortPflanzungsWasser + (3*Leb1WasserOhneBewegung))) and
         (Lebensform1[i].bFortpflanzen = false) then Lebensform1[i].bFortpflanzen := true;
      if Lebensform1[i].bFortpflanzen = true then
        begin
          if Lebensform1[i].iSchwanger < Leb1Schwanger then
            begin
              Lebensform1[i].iNahrung := Lebensform1[i].iNahrung - Leb1NahrungOhneBewegung;
              Lebensform1[i].iWasser := Lebensform1[i].iWasser - Leb1WasserOhneBewegung;
              Lebensform1[i].iSchwanger := Lebensform1[i].iSchwanger + 1;
            end
          else
            begin
              Lebensform1[i].iSchwanger := 0;
              Lebensform1[i].bFortpflanzen := false;
              Lebensform1[i].iNahrung := Lebensform1[i].iNahrung - Leb1FortPflanzungsNahrung;
              Lebensform1[i].iWasser := Lebensform1[i].iWasser - Leb1FortPflanzungsWasser;
              SetLength(LebenTemp,Length(Lebensform1));
              for iIndex := 0 to Length(LebenTemp)-1 do
                begin
                  LebenTemp[iIndex].ix := Lebensform1[iIndex].ix;
                  LebenTemp[iIndex].iy := Lebensform1[iIndex].iy;
                  LebenTemp[iIndex].iNahrung := Lebensform1[iIndex].iNahrung;
                  LebenTemp[iIndex].iWasser := Lebensform1[iIndex].iWasser;
                  LebenTemp[iIndex].iSchwanger := Lebensform1[iIndex].iSchwanger;
                  LebenTemp[iIndex].bFortpflanzen := Lebensform1[iIndex].bFortpflanzen;
                end;
              SetLength(Lebensform1, Length(LebenTemp)+8);
              for iIndex := 0 to Length(LebenTemp)-1 do
                begin
                  Lebensform1[iIndex].ix := LebenTemp[iIndex].ix;
                  Lebensform1[iIndex].iy := LebenTemp[iIndex].iy;
                  Lebensform1[iIndex].iNahrung := LebenTemp[iIndex].iNahrung;
                  Lebensform1[iIndex].iWasser := LebenTemp[iIndex].iWasser;
                  Lebensform1[iIndex].iSchwanger := LebenTemp[iIndex].iSchwanger;
                  Lebensform1[iIndex].bFortpflanzen := LebenTemp[iIndex].bFortpflanzen;
                end;
              iIndez := 0;
              for iIndex := -1 to 1 do
                begin
                  for iIndey := -1 to 1 do
                    begin
                      if (iIndey = 0) and (iIndex = 0) then
                      else
                        begin
                          Lebensform1[Length(LebenTemp)+iIndez].ix := Lebensform1[i].ix-iIndex;
                          Lebensform1[Length(LebenTemp)+iIndez].iy := Lebensform1[i].iy-iIndey;
                          Lebensform1[Length(LebenTemp)+iIndez].iNahrung := 0;
                          Lebensform1[Length(LebenTemp)+iIndez].iWasser := 0;
                          Lebensform1[Length(LebenTemp)+iIndez].iSchwanger := 0;
                          Lebensform1[Length(LebenTemp)+iIndez].bFortpflanzen := false;
                          iIndez := iIndez+1;
                        end;
                    end;
                end;
            end;
        end
      else
        begin
          while Lebensform1[i].iBewegung > 0 do
            begin
              Feld_ueberpruefen(Lebensform1[i]);
              Bewegen(Lebensform1[i]);
            end;
        end;
    end;

end;

procedure Welt_aendern;
var i, j: integer;
begin
  for i := 0 to 504 do
    begin
      for j := 0 to 496 do
        begin
          Welt[i,j].iNahrung := Welt[i,j].iNahrung + random(3);
          Welt[i,j].iWasser := Welt[i,j].iWasser + random(3);
        end;
    end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Lebensform_versetzen;
  Welt_aendern;
  Weltzeichnen;
  Bildzeichnen;
  TreeView_anpassen;
end;

end.
Also für alle die das erstmal nicht alles durchschauen wollen hier eine kurze Erklärung dazu. Es stellt erstmal eine Simulation einer einfachen Lebensform dar, die NAhrung und Wasser sammelt und sich auf dieser Grundlage wie die Einzeller durch Zellteilung fortpflanzt. Jetzt mein Problem. ab dem ca 1000 wird die Berechnungszeit sämtlicher "Aktivitäten" deutlich länger als das Intervall für den Timer. Kennt jemand eine Möglichkeit mit denen ich die Berechnungen deutlich schneller durchführen kann? Wäre über jede Idee dankbar.

Vielen Dank
BAMatze
  Mit Zitat antworten Zitat