Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Wator - Problem mit Arrayberechnung (https://www.delphipraxis.net/64513-wator-problem-mit-arrayberechnung.html)

monta 4. Mär 2006 14:57


Wator - Problem mit Arrayberechnung
 
Ich versuche gerade eine einfache Wator - Simulation (Räuber-Beute-Modell) zu programmieren. Alle denen WATOR nichts sagt, können hier nachlesen Wikipedia - Wator.

Jedoch hab ich bei der Berechnung der nächsten Generation das Problem, das das Programm nach einigen neuen Generationen sich komplett aufhängt. Je mehr Individuen ich dabei zu Begin setze, desto eher hängt sich das Programm auf. Irgendetwas in meiner Prozedure sogrt vermutlich für einen Speicherüberlauf oder eine entlosschleife, jedoch habe ich keine Ahnung, wo der Fehler liegt.

Hier nun mal mein Code:

Delphi-Quellcode:
procedure TForm1.StartClick(Sender: TObject);
var x, y: integer;
    x2, y2: integer;
    Nachbarn: integer;
    tempWator: TWator; //Array [0..124, 0..124] of Record aus Gattung, Fasten, Alter: jeweils integer
begin
  randomize;
  for x := 1 to 123 do
  begin
    for y := 1 to 123 do
    begin

      x2 := x;
      y2 := y;
      if Wator[x, y].Gattung <> 0 then //0 markiert leere Felder
      begin
        Nachbarn := Nachbarschaft(x, y); //Nachbarschaft ermittel ob ein Feld in der Umgebung frei ist bzw. ein Hai einen Fisch finden kann
        if Nachbarn in [1, 2] then
        begin
          repeat  //ermittelt freies Nachbarfeld
            x2 := x;
            y2 := y;
            case Random(4) of
              1: inc(x2);
              2: dec(x2);
              3: inc(y2);
              4: dec(y2);
            end;
          until ((Wator[x2, y2].Gattung = 0) and (Nachbarn = 1)) or //Abbruch bei Fischen sobald ein freies Nachbarfeld gefunden wurde
            ((Wator[x2, y2].Gattung = 2) and (Nachbarn = 2)); //bei Haien, wenn sie einen Fisch gefunden haben (falls überhaupt verfügbar)
        end;
      end;

      tempWator[x2, y2].Gattung := Wator[x, y].Gattung;  //tempWator dient als Zwischenspeicher für für
      tempWator[x2, y2].Alter := Wator[x, y].Alter + 1;  //nächste Generation
      tempWator[x2, y2].Gattung := Wator[x, y].Fasten + 1;

    end;
  end;
    Wator := tempWator; //geändert
    PaintWator;  //gibt Array grafisch aus
    ShowMessage('Ende'); //als Test, ob durchlauf abgeschlossen
end;

sämtliche speziellen Routinen wie Vermehrung fehlen natürlich noch.

Vielleicht sieht jemand die Stelle, wo der Overhead - oder sonstwas - entsteht.

ConstantGardener 5. Mär 2006 10:26

Re: Wator - Problem mit Arrayberechnung
 
Hallo monta,

ich sehe bei dir kein Application.ProcessMessages in der Schleife. Die Anwendung gibt keinem anderen Programmteil bzw. der VCL Gelegenheit Ausgaben/Eigaben usw. zu ermöglichen. Ruf die Methode mal mit auf, vielleicht hilfts...

Oder du lagerst die Sache in nen eigenen Thread aus !?

monta 5. Mär 2006 12:06

Re: Wator - Problem mit Arrayberechnung
 
Danke für die Hilfe, aber ein Aufruf von Processmessage ändert nichts, außer das ich während der eigentlichen Berechnung Eingaben machen kann. Dennoch bricht er aber die Procedure nach einer gewissen Zeit, bzw erst nach mehreren Durchläufen (je nach Fischzahl) ab und ich bekomme einen StackOverflow.

Nur was löst diesen aus?

Die Procedure in einen Thread auszulagern war schon geplant, aber das wollte ich erst machen, wenn sie auch geht.

Hawkeye219 5. Mär 2006 12:16

Re: Wator - Problem mit Arrayberechnung
 
Hi monta,

wenn ich das richtig sehe, überprüfst Du an keiner Stelle die als Index benutzten Variablen x2 und y2, wodurch in der Repeat-Schleife der zulässige Bereich (bei Dir 0..124) verlassen werden kann. Beim Schreibzugriff auf das Feld tempWator[] dürft dann der Fehler auftreten. Um meine Theorie zu überprüfen, kannst Du ja mal in den Compileroptionen die Bereichsüberprüfung einschalten. Wenn Du dann das Programm in der IDE laufen läßt, sollte Dir die fehlerhafte Zeile angezeigt werden.

Noch was: Du greifst nach den beiden For-Schleifen auf die Schleifenvariablen x und y zu. Laut Delphi-Hilfe ist der Inhalt einer Schleifenvariable außerhalb der Schleife undefiniert.

monta 5. Mär 2006 12:30

Re: Wator - Problem mit Arrayberechnung
 
Da die for-schleife von 1 bis 123 geht und ich die Variblen maximal um eins verringere bzw erhöhe, dürfte der Bereich doch nicht überschritten werden :gruebel:
Die Bereichsprüfung war auch beim testen die ganze Zeit aktiviert und hat nkeinerlei Fehler gemeldet.

Zitat:

Noch was: Du greifst nach den beiden For-Schleifen auf die Schleifenvariablen x und y zu. Laut Delphi-Hilfe ist der Inhalt einer Schleifenvariable außerhalb der Schleife undefiniert.
Stimmt, wa aber nur ein Fehler bei der Eingabe hier, da ich davor zuerst noch eine for-Schleife stehen hatte. Die richtige Zuweisung heißt natürlich
Delphi-Quellcode:
Wator := tempWator;
hab ich oben schon geändert

Hawkeye219 5. Mär 2006 13:34

Re: Wator - Problem mit Arrayberechnung
 
Stimmt, ich hatte übersehen, daß Du in der Repeat-Schleife die Variablen x2 und y2 initialisierst. :oops:

Aber einen kleinen Fehler gibt es: Random(4) liefert nur Werte im Bereich 0..3!

Airblader 5. Mär 2006 21:21

Re: Wator - Problem mit Arrayberechnung
 
Kann es sein, dass es sich bei der Abbruchbedingung der repeat-Schleife verheddert, weil es sein kann, dass ein Hai eben keinen Fisch in seiner Umgebung hat und die Schleife sich dadurch aufhängt?
Denn bei dir muss - soweit ich das sehe - ein Hai einen Fisch finden. Findet er keinen, so soll er ja weiterschwimmen. Bei dir hängt sich das ganze allerdings auf, glaube ich ;)

MfG, air

monta 11. Mär 2006 11:51

Re: Wator - Problem mit Arrayberechnung
 
Danke für eure Hilfe, ich hab meinen Fehler gefunden...er hat wirklich nicht aus der Schleife gefunden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:21 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