Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Hilfe bei einer Simulation (https://www.delphipraxis.net/126727-hilfe-bei-einer-simulation.html)

BAMatze 1. Jan 2009 01:06


Hilfe bei einer Simulation
 
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 starten' then
    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

omata 1. Jan 2009 01:15

Re: Hilfe bei einer Simulation
 
Zeige uns doch bitte deinen Quellcode als Anhang mit allen benötigten Dateien. Dann macht das ganze mehr sinn und eventuell auch spass.

BAMatze 1. Jan 2009 01:20

Re: Hilfe bei einer Simulation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von omata
Zeige uns doch bitte deinen Quellcode als Anhang mit allen benötigten Dateien. Dann macht das ganze mehr sinn und eventuell auch spass.

Hier alles, was ich dazu angelegt hab

Torpedo 1. Jan 2009 01:53

Re: Hilfe bei einer Simulation
 
Wenn du die Liste auf dem Fenster weglassen würdest, wäre es schon um einiges schneller.

BAMatze 1. Jan 2009 07:56

Re: Hilfe bei einer Simulation
 
Also hab das jetzt mal getestet und bei mir ändert sich dadurch nicht allzu viel. Es fängt eventuell erst bei der folgenden Teilung an mit den "riesigen" PAuse aber es geht mir ja darum, ob es Möglichkeiten gibt, die Berechnungen anders durchzuführen und damit ein konstanten zeitlichen Zwischenraum zu erreichen, obwohl sich die Zahl der "Lebewesen" weiter vergrößert.

Klaus01 1. Jan 2009 09:50

Re: Hilfe bei einer Simulation
 
Guten Morgen und ein frohes neues Jahr.

Ich habe mir mal Deinen Code angeschaut.

Dies ist aus der Procedure Leben_versetzen.

Delphi-Quellcode:
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;
Wenn Du dir das einmal genauer anschaust, wirst Du wahrscheinlich
auch feststellen, dass die letzten 8 Werte des Arrays Lebensform1 nicht initialisiert
werden.
In den .ix und .iy Feldern stehen irgendwelche undefinierten Werte und das
führt zu Problemen in der Procedure
Delphi-Quellcode:
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;
Wenn da sehr große negative Werte für ix und iy stehen
kann es eine Zeit lang brauchen bis .ix und .iy größer als 1 sind.

Wenn dann Dein Timer immer noch Problem machen sollte,
kannst Du ihn ja während der Berechnung uns Zeichnung deaktivieren.
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  (sender as TTimer).Enabled:=false;
  Lebensform_versetzen;
  Welt_aendern;
  Weltzeichnen;
  Bildzeichnen;
  TreeView_anpassen;
  (sender as TTimer).Enabled:=true;
end;
.. und noch ein Nachtrag.

Wenn Du Deine Unterprogramme zu Methoden Deiner Form machst.
Dann kannst Du dir Konstrukte wie diese:
Delphi-Quellcode:
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;
Würde dann so aussehen:

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

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

end;
.. und hat den Vorteil, wenn Du das Formular mal umbenennst
von Form1 nach Simulation o.ä. Du im QuellCode
nicht mehr allzuviel ändern mußt.



Grüße
Klaus

BAMatze 1. Jan 2009 10:07

Re: Hilfe bei einer Simulation
 
Zitat:

Zitat von Klaus01
Guten Morgen und ein frohes neues Jahr.

Ich habe mir mal Deinen Code angeschaut.

Dies ist aus der Procedure Leben_versetzen.

Delphi-Quellcode:
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;
Wenn Du dir das einmal genauer anschaust, wirst Du wahrscheinlich
auch feststellen, dass die letzten 8 Werte des Arrays Lebensform1 nicht initialisiert
werden.
Klaus

Hallo Klaus, dir auch Gesundes Neues Jahr und natürlich auch allen anderen. Die Initialisierung der restlichen 8 "Lebensformen" erfolgt, wenn auch etwas unkonventionell über die folgenden 2 For-Schleifen. Hier nochmal der Auszug:

Delphi-Quellcode:
              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;
Dies funktioniert auch. Dafür hatte ich das TreeView überhaupt erst eingeführt, damit ich die Werte welche die "Lebensformen" haben überprüfen kann. Insgesamt läuft das Programm so wie ich es hier online gestellt hab. Wie gesagt, das Problem ist einfach die Zeit zur Berechnung der gesammten Aktionen insgesamt.

Hab jetzt gelesen, dass man Threats machen kann. Leider hab ich damit noch keine Erfahrung. vieleicht kann mal jemand, der sowas schonmal gemacht hat über den Code schauen und mir sagen, wie man das anlegen kann.

Danke
BAMatze

BAMatze 1. Jan 2009 11:51

Re: Hilfe bei einer Simulation
 
Habe mal versucht nach einem Beispiel von dieser Seite: Michael Puff meine Bewegung in einen Thread auszulagern. Das Programm liefert mir faktisch keinen Fehler zurück, was nicht bedeutet, dass ich keinen gemacht hab. Das Ergebnis ist noch nicht wirklich dem was ich mir erhofft habe, da sich nun die "Lebensform" erstmal nicht bewegt. Vieleicht kann jemand mal schnell drüber schauen, wo der Fehler liegt.

Hier der neue 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;
  PLebensform = ^TLebensform;

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

var
  Form1: TForm1;
  Lebensform1: array of TLebensform;
  Welt: array of array of TOrt;
  brun: integer = 1;



implementation

procedure Bewegen(var Objekt: TLebensform);
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;
              //Form1.Button1Click(nil);
            end;
        end
      else
        begin
          while Lebensform1[i].iBewegung > 0 do
            begin
              Feld_ueberpruefen(Lebensform1[i]);
              Bewegen(Lebensform1[i]);
            end;
        end;
    end;

end;

function ThreadLeben(p: pointer):integer;
begin
  result := 0;

  while brun = 0 do
    begin
      ShowMessage('Hallo');
      Lebensform_versetzen;
      sleep(0);
    end;
end;

{$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 starten' then
    begin
      brun := 0;
      Timer1.Enabled := true;
      Button1.Caption := 'Simulation stoppen';
    end
  else
    begin
      brun := 1;
      Timer1.Enabled := false;
      Button1.Caption := 'Simulation starten';
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
    p: Pointer;
    ThreadLebenID: LongWord;
begin
  getMem(p, Sizeof(TLebensform));
  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;
  CloseHandle(BeginThread(nil, 0, @ThreadLeben, p, 0, ThreadLebenID));
  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 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.
Hoffe jemand sieht meinen Fehler und kann ihn mir mitteilen.

Danke

Klaus01 1. Jan 2009 13:11

Re: Hilfe bei einer Simulation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich nochmal.
Ich gehe immer noch davon aus, dass im Array Lebensform1
nicht alle Elemente initialisiert wurden denn woher sollten
sonst Werte von -53433 für .ix kommen.
(siehe Bild im Anhang).

Damit die Procedure bewegen von diesem Wert auf einen
Wert > 1 kommt, da geht schon einige Zeit ins Land.

Delphi-Quellcode:
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;
Wenn das Problem nicht behoben wird, nützt auch ein Thread nichts.

Grüße
Klaus

BAMatze 1. Jan 2009 13:24

Re: Hilfe bei einer Simulation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hmm das kann ich mir gerade auch nicht erklären. Habe jetzt mal das Programm so abgeändert, dass es genau nach der ersten Teilung stoppt und dann im TreeView alle Werte von den "Lebensformen" ausgegeben. Ich stelle dir die gesamte Datei nochmal rein, dann kannst du selber schauen. Ich hoffe es liegt nicht an unterschiedlichen Betriebssystemen. Ich verwende hier Vista.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz