Autor Beitrag
Dornathal
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Do 08.11.07 21:04 
Ich weis es wurden schon einige andere Themen mit gleichem Inhalt hier eröffnet, aber ich habe durch das lesen nicht mein Problem aufheben können.

Es geht um das Problem mit dem Überkreuzenden Bezug zweier Units.

Ich habe mehrere Units, die alle zusammen eine Simulation eines Stadtverkehrs (mit Ampeln, Kreuzungen und Strassen sowie Autos ergeben soll.) Nun stehe ich vor dem problem, dss die Autos an den Kreuzungen ordnungsgemäß abbiegen sollen.

Die beteiligten Units sind:
TKreuzung und TStrasse
Ich habe mir das so gedacht, dass die Kreuzung an bis zu 4 Strassen "angeschlossen" wird, und beim überfahrenwerden eines Autos dieses auf die umliegenden Strassen verteilt per random.

==> Dazu muss natürlich die Klasse TStrasse die Tkreuzung kennen, um ihr zu sagen "hier is schon wieder nen Auto für dich zum verteilen"... Nun muss die Kreuzung das Auto auf eine der drei anderen Strassen abschieben. Also muss auch diese Klasse die TStrasse kennen.

Nun hab ich allerdings überschneidende Bezüge
(Wir sollen noch nicht zwei Klassen in eine Unit reinstecken, sondern für jede Klasse eine machen)

Ich hab mir dafür eine Dreiecksbeziehung ausgedacht.

TStrasse kennt TKreuzung und übergibt dieser das Auto das diese dann auf die anderen Strassen verteilen soll.
Die TKreuzung kennt wieder eine TStrassenkreuzung die diese Strassen kennt und das per random abwickeln soll.
TStrassenkreuzung kennt 4 TStrassen von denen dann eine ausgewählt wird die das auto dann weiter folgt.

So hab ich das verstanden dass es funktionieren sollte. (In den anderen Foren) Aber es klappt trotzdem noch nicht, ich habe trotzdem einen überkreuzenden Bezug.

Blöderweise hab ich jetzt keine Ahnung woran das liegen könnte, deswegen wollt ich das hier mal erfragen. Hoffe es gibt eine unkomplizierte Lösung.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
unit mKreuzung;

interface
  uses mSuM, mAuto, mAmpel ,mStrassenkreuzung;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
unit mStrassenkreuzung;

interface
  uses   mAuto, mStrasse;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
unit mStrasse;

interface
  uses mSuM,math, mAuto, mKreuzung;


Da müssten ja die Überkreuzende Beziehung enthalten sein.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 08.11.07 22:43 
Das Problem ist, dass mKreuzung.pas noch nicht komplett abgearbeitet ist, wenn die Unit über mStrassenkreuzung und mStrasse wieder benötigt wird. Und das ändert sich auch nicht, wenn du die Einbindung über 100 Units verteilst...

Die einzige Lösung ist, dass du statt dass TStrasse die Klasse TKreuzung kennt, nur ein TObject kennt. Dann musst du das bei Verwendung casten:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  TStrasse = class
  public
    Kreuzung: TObject;
  end;

...

implementation

uses
  mKreuzung;

...

  TKreuzung(Strasse1.Kreuzung).TueWas;
Unterhalb von implementation kannst du eine Unit auch dann einbinden, wenn diese wieder die erste in der Uses-Klausel unterhalb von interface eingebunden hat.

Das steht in anderen Threads zu dem Thema aber auch drin...
Dornathal Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Fr 09.11.07 21:33 
Hmm sieht soweit schlüssig aus. hab aber erst jetzt kapiert dass es die Lösung für mein problem ist ... sry;

==> Wollt halt noch nicht soooo weit dem Unterricht vorraus.

Das Programm funktioniert soweit gut. Bloss habe ich nun das folgende Problem. Bei dem Auufruf dieser Funktion schliesst das programm ohne Fehlermeldung etc. => Bildschirm ist einfach weg.
ausblenden Delphi-Quelltext
1:
TStrasse(self.kenntStrasse[zStrasse]).bekommeAuto(pAuto);					


TStrasse = class der Strasse;
self ist in diesem Fall die kreuzung die die Autos verteilen soll
kenntStrasse ist ein dynamisches Array mit den Strassen die die Kreuzung kennt.
=> ist in der Kreuzung deklariert.
zStrasse ist die aktuelle Anzahl der Strassen in kenntStrasse => hab die funktion für die länge eines dynamischen Arrays bisher nciht gefunden.

pAuto ist das Aut das überreicht wird.
in der funktion soll vorher noch ein random stattfinden, sodass die Autos willkürlich verschiedenen Strassen folgen. Deshalb der zwischenschritt über diese Kreuzung.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 09.11.07 22:29 
Naja, also ohne den Quelltext kann ich da nix zu sagen. Weil was da passiert, das kann ich ja so nicht wissen, da könnte ich höchstens raten.

Auch wenn es nicht zum Thema des Threads gehört: Länge eines dynamischen Arrays setzen - SetLength, Länge auslesen - Length ;-).
Dornathal Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Fr 09.11.07 22:37 
Oke dann hab ich mal hier den Quelltext, über die verständlichkeit weis ich allerdings momentan noch nichts.

*Edited* noch das Auto mit hinzugefügt.
Einloggen, um Attachments anzusehen!
Dornathal Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Sa 10.11.07 13:34 
Das passt ldeider nicht mehr in den alten Beitrag.

Hier ist das komplette Programm mal.
Das was auskommentiert ist hat irgendwie zu fehlern geführt. Da weis ich auch noch nicht weiter.

das kommt erst nach dem doppelklick.

*Edited*
Also irgendwie muss der Fehler in diesem Teilstück liegen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TKreuzung.setzeStrasse(pStrasse: TObject);
  var lStrassen: Integer;
  begin
    lStrassen:= Length(kenntStrasse) + 1;
    setlength(kenntStrasse,lStrassen);
    kenntStrasse[lStrassen]:= pStrasse;
  end


Denn wenn man  TStrasse(self.kenntStrasse[zStrasse]).bekommeAuto(pAuto);
Ausführen will kommt ja der Fehler. Kann es sein, dass man keine dynamischen Arrays in so einer Art benutzen darf?

Und liegt der Fehler vielleicht auch in dem parameter pStrasse, der zum Zeitpunkt der uebergabe noch vom typ TStrasse aufgerufen wird? => nämlcih mit self in dem constructor der Strassenklasse
Muss ich das vielleicht ausserhalb des constructors machen, weil dann die Strasse noch nicht ganz existiert oder so ähnlich?
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 10.11.07 19:31 
Ich habe jetzt mSum im Internet gefunden. Jetzt verstehe ich auch erst warum das ganze so kompliziert aussieht^^.
Warum manche Lehrer den Schülern nur immer das Leben schwer machen müssen anstatt ganz normal Delphi (oder wie bei uns Java) beizubringen... Wir haben das ganz normal gelernt und so wie wir es gelernt haben, kann man auch später was damit anfangen, wenn man das will oder muss. Egal, das ist ja nicht mein Problem^^.

Jedenfalls habe ich das Programm kompiliert und ausgeführt und jetzt flitzen eine rote und eine blaue Kugel immer unten hin- und her. Aber wo tritt jetzt ein Fehler auf? Bzw. was SOLL denn passieren?
Dornathal Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Sa 10.11.07 22:03 
Upps dann hab ich wohl ne falsche version hochgeladen, denn ich hab den kreislauf mit dem Uebergeben ausgeklammert, indem sich die Strasse den Ball immer Selbst uebergibt, sodass esnicht in die Kreutzung reinmuss.

deswegen erstze mal in TStrasse das
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TStrasse.uebergebeAuto (pAuto: TAuto);
begin
    kenntKreuzungen[1].uebergebeAuto(pAuto);
end;
Oder in dem Auto
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TAuto.Fahre;
  begin
    hatStift.setzeFarbe(GRAU);
    self.zeigeDich;
    hatStift.bewegeUm(zGeschwindigkeit);
    hatStift.setzeFarbe(zFarbe);
    self.zeigeDich;
    if (self.AmStrassenEnde) then
      begin
      //zGeschwindigkeit:= 0;
      hatStift.setzeFarbe(GRAU);
      self.zeigeDich;
      TStrasse(self.kenntStrasse).uebergebeAuto(self); // das funktioniert ja...
      end;
  end;


Das hab ich dann glaub ich umgeändert...

Im endeffekt sollen iese Punkte Autos darstellen. Die siesen Strassen folgen. Wenn sie dann irgendwann einmal an eine Kreuzung kommen weil diese grade im Weg ist sollen sie auf eine Andere Strasse wechslen ohne ihrer Strasse diekt wieder zurückzufahren. <<== Das ist ja das was du siehst.

Deshalb hab ich bdas momentan so dass die Autos mitten auf die Kreuzung fahren und dann ihrer Strasse sagen sie sollen der Kreuzung bescheid sagen dass sie gerne auf ne andere Strasse wollen. Deswegen muss ja die Strasse die Kreuzung kennen, und die Kreuzung dann wieder alle Strassen die an ihr enden um dann eine neue Strasse für das Auto auszuwählen und dieser Strasse dann zu sagen dass sie das Auto die neue Richtung zuweisen sollen etc.

Das ist so mein Gedankengang... <== mit dem hab ich wenigstens schon mal hinbekommen dass es keine Ueberkreuzende Bezüge Fehlermeldungen mehr gibt. Dafür stürzt das immer ab sobald die Kreuzung ihre Methode uebergebeAuto ausführen soll. Da muss iwo der Wurm drin sein. Bloss ich weis nicht wo ich hab auch alles so gemacht wie das im Bezug auf Ueberkreuzende Bezüge mir hier gesagt wurde...


Hmm ich denke die Lehrer benutzen die mSuM weil das vom Land so vorgeschrieben ist ... glaub ich.
Ausserdem meinen Sie es sei damit einfach das zu lernen, da die ganzen Begriffe einfacher zu merken seien...

Ich bin da pers. nicht so überzeugt von denn das problem ist, dass man meiner Meinung nach dann zwei mal was auswendig lernen muss... Das Deutsche und das Englische... Während man nämlich eine Procedure mit einem Parameter des types "Zahl" füllt, (Real) wird einem beim Aufruf dieser Procedure der Datentyp Real abverlangt.
Ein anderes Großes Manko ist die bedienung der Tastatur. Hat man nun zwei oder mehr klassen die alle gleich auf die Eingabe eines zeichens reagieren sollen, muss dieses zwischengespeichert werden. Denn sobald man das zeichen einmal aus der Tastatur abfragt, muss es wieder gelöscht werden ansonsten kommen mSuM's Kritischen Errormeldungen: "Es ist ein schwerwiegender fehler im Umgang mit der Tastatur aufgetreten!" << ich würd mal sagen präzise Meldung, bei der man sofort den fehler debuggen kann...

Ich habe schon einiges in VB 6 und PHP SQL gemacht sodass ich schon son bisserl mit den ganzen Sachen besser umgehen kann als meine Klasse was ja auch nciht weiter schlimm ist. Aber so wie ich einmal VB gelernt hab ist das schon ein bisserl dämlich finde ich.
Einloggen, um Attachments anzusehen!