AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Hilfe bei einer Simulation

Ein Thema von BAMatze · begonnen am 1. Jan 2009 · letzter Beitrag vom 3. Jan 2009
Antwort Antwort
Seite 1 von 2  1 2   
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, 01: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
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 01:15
Zeige uns doch bitte deinen Quellcode als Anhang mit allen benötigten Dateien. Dann macht das ganze mehr sinn und eventuell auch spass.
  Mit Zitat antworten Zitat
BAMatze

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

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 01:20
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
Angehängte Dateien
Dateityp: rar lebenssimulation_416.rar (205,1 KB, 15x aufgerufen)
  Mit Zitat antworten Zitat
Torpedo

Registriert seit: 21. Dez 2003
410 Beiträge
 
#4

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 01:53
Wenn du die Liste auf dem Fenster weglassen würdest, wäre es schon um einiges schneller.
  Mit Zitat antworten Zitat
BAMatze

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

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 07:56
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.
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.753 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 09:50
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
Klaus
  Mit Zitat antworten Zitat
BAMatze

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

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 10:07
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
  Mit Zitat antworten Zitat
BAMatze

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

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 11:51
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 startenthen
    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
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.753 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 13:11
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
Miniaturansicht angehängter Grafiken
simleben_282.png  
Klaus
  Mit Zitat antworten Zitat
BAMatze

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

Re: Hilfe bei einer Simulation

  Alt 1. Jan 2009, 13:24
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.
Angehängte Dateien
Dateityp: rar lebenssimulation_144.rar (207,9 KB, 5x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:39 Uhr.
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