Problem mit Textadventure

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
HomerSimpson07
Beiträge: 4
Registriert: Sa 17. Sep 2011, 22:54

Problem mit Textadventure

Beitrag von HomerSimpson07 »

Hallo,

ich muss für die Schule mit Lazarus ein Textadventure programmieren, und da sollen auch Items gefunden werden können.
Den Code für das Items finden hab ich mir aus einem entsprechenden Delphi-Textadventure geholt, nun funktioniert dieser Code bei Lazarus aber nicht, es kompiliert das Programm zwar fehlerfrei, aber wenn ich dann in einen Raum komme wo ein Item gefunden werden soll dann kommt die Fehlermeldung "Projekt textadventure.exe hat Exception-Klasse External: SIGSEGV ausgelöst."

Das ist der Code der den Fehler auslöst (glaube ich zumindest):

Code: Alles auswählen

procedure TRucksack.hinzufuegen ( found:String);
var i : integer ;
begin
i := 1;
while (i <= 5) do
 
begin
  if (self.item[i]=found)  then
  break
  else
  if self.item[i]= '' then
    begin
    self.item[i] := found;
    break
    end;
  inc(i);
end;
Bei Delphi funktioniert dieser Code wie gesagt einwandfrei, aber mit Lazarus nicht. Das Programm muss aber unbedingt mit Lazarus geschrieben sein, unser Lehrer will das so.

Also hoffe ich ihr könnt mir sagen was ich an dem Code ändern muss damit er auch mit Lazarus funktioniert, schonmal Danke im Vorraus :)
Zuletzt geändert von Lori am So 18. Sep 2011, 12:59, insgesamt 1-mal geändert.
Grund: richtiger Highlighter

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Problem mit Textadventure

Beitrag von Socke »

Willkommen im Forum und ein Lob an deinen Lehrer :D
HomerSimpson07 hat geschrieben:Das ist der Code der den Fehler auslöst (glaube ich zumindest)
Zeigt Lazarus nicht die Stelle im Quelltext an, an der sich dein Programm verabschiedet bzw. kannst du den Code soweit isolieren (in einem extra-Programm), dass nichts anderes passiert, als den Fehler zu produzieren?

Mein erster Ansatz wäre, dass in der Schleife, die du zitierst, versucht wird, auf ein nicht initialisiertes Array zuzugreifen. Als zweites kommt mir die Frage in den Sinn, ob du überhaupt ein Objekt erstellt hast. Für genauere Antworten brauche ich mehr Code (wie erstellst du den Rucksack, wie greifst du darauf zu und wie ist der Rucksack überhaupt implementiert).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

HomerSimpson07
Beiträge: 4
Registriert: Sa 17. Sep 2011, 22:54

Re: Problem mit Textadventure

Beitrag von HomerSimpson07 »

Die stelle die angezeigt wird wenn sich das Programm verabschiedet ist diese hier:

Code: Alles auswählen

Rucksack.Hinzufuegen(aktuellerRaum.Gegenstand);
Also die Stelle wo die Prozedur abgerufen wird. Deswegen denke ich, dass das Problem in dem Code der Prozedur liegt.

Zuerst wird TRucksack als Klasse erstellt:

Code: Alles auswählen

type
  TRucksack = class
    Item : Array [1..3] of string;
    procedure Hinzufuegen (found :string);
    function Ausgeben : string;
    function Voll : boolean;
    end;
und dann wird Rucksack als Variable vom Typ TRucksack erstellt:

Code: Alles auswählen

var
  Form1: TForm1;
  [...]:TRaum;
  Rucksack: TRucksack;
Also initialisiert ist das Array, ein Objekt ist damit wohl auch erstellt.
Der Fehler liegt also denk ich woanders, oder ist da irgendwas falsch?
Zuletzt geändert von Lori am So 18. Sep 2011, 12:59, insgesamt 1-mal geändert.
Grund: richtiger Highlighter

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Problem mit Textadventure

Beitrag von Scotty »

Item : Array [1..3] of string; und while (i <= 5) do passen nicht so richtig zusammen. Entweder 0 (das ist besser, als mit 1 zu beginnen) bis 2 oder <=3 oder gleich eine TStringList nehmen.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Problem mit Textadventure

Beitrag von mschnell »

High() und Low() geben die grenzen des Index eines Feldes an (do i := Low(feld) to High(feld)).

-Michael

HomerSimpson07
Beiträge: 4
Registriert: Sa 17. Sep 2011, 22:54

Re: Problem mit Textadventure

Beitrag von HomerSimpson07 »

Scotty hat geschrieben:Item : Array [1..3] of string; und while (i <= 5) do passen nicht so richtig zusammen. Entweder 0 (das ist besser, als mit 1 zu beginnen) bis 2 oder <=3 oder gleich eine TStringList nehmen.
Hab es korrigiert, das hat aber nicht geholfen, der Fehler tritt immernoch auf.
mschnell hat geschrieben:High() und Low() geben die grenzen des Index eines Feldes an (do i := Low(feld) to High(feld)).

-Michael
Das verstehe ich nicht ganz, wo genau soll ich das denn einbauen, und wofür steht "feld", also was soll ich da rein schreiben?

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Problem mit Textadventure

Beitrag von Socke »

HomerSimpson07 hat geschrieben:Das verstehe ich nicht ganz, wo genau soll ich das denn einbauen, und wofür steht "feld", also was soll ich da rein schreiben?
Ein Array ist eine Folge von mehreren Variablen eines bestimmten Typs, in diesem Fall einer Zeichenkette (String). Die einzelnen Bestandteile eines Arrays nennt man Feld. Auf die einzelnen Felder kann man mit einem Index (in eckigen Klammern hinter dem Array-Namen) zugreifen. Die beiden Funktionen low() und high() geben den niedrigsten beziehungsweise höchsten Index des Arrays zurück.
Ich habe deinen Quelltext ein wenig kommentiert

Code: Alles auswählen

procedure TRucksack.hinzufuegen ( found:String);
var i : integer ;
begin
// in der Schleife wird i als Index verwendet
i := 1;  // hier wird der niedrigste Index gesetzt (1 durch low(self.item) ersetzen)
while (i <= 5) do  // die Schleife läuft so oft, bis der Index 5 überschritten hat; der Array hat aber den höchsten Index 3 (oder high(self.item)
 
begin
  if (self.item[i]=found)  then
  break
  else
  if self.item[i]= '' then
    begin
    self.item[i] := found;
    break
    end;
  inc(i);  // hier wird der Index um 1 erhöht (nächster Gegenstand)
end;
HomerSimpson07 hat geschrieben:und dann wird Rucksack als Variable vom Typ TRucksack erstellt:

Code: Alles auswählen

var
  Form1: TForm1;
  [...]:TRaum;
  Rucksack: TRucksack;
Also initialisiert ist das Array, ein Objekt ist damit wohl auch erstellt.
Bei Objekten reicht es nicht aus, eine Variable für sie bereitzustellen. Bevor du auf den Rucksack zugreifst, musst du das Objekt auch erstellen (zum Beispiel bei Programmstart, oder wenn Form1 erstellt wird).

Code: Alles auswählen

Rucksack := TRucksack.Create;
Sobald du es nicht mehr brauchst (Programmende), musst du das Objekt auch wieder freigeben

Code: Alles auswählen

Rucksack.Destroy;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

HomerSimpson07
Beiträge: 4
Registriert: Sa 17. Sep 2011, 22:54

Re: Problem mit Textadventure

Beitrag von HomerSimpson07 »

Das TRucksack.Create hat geholfen, es funktioniert jetzt :D

Vielen Dank für eure Hilfe :)

/edit:

Jetzt habe ich allerdings ein anderes Problem: Das Item wird nun einmal beim Betreten eines Raumes mit Item gefunden, und dann nochmal beim Verlassen. Ich habe dann also zweimal das gleiche Item. Wenn ich den Raum dann anschliessend nochmal betrete finde ich das Item aber nicht erneut. Also merkt das Programm anscheinend erst, dass das Item schon gefunden wurde nachdem ich den Raum verlassen habe, aber noch nicht in dem Moment wo ich es zum ersten mal finde.

Weiß jemand woran das liegen kann?

/edit2:
Hat sich erledigt, hab den Fehler selbst gefunden, es hat ein Memo.Lines.Clear gefehlt.

Antworten