Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit Programm (https://www.delphipraxis.net/84164-problem-mit-programm.html)

schuetzejanett 12. Jan 2007 13:26


Problem mit Programm
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

Weiß zwar nicht ob ich dafür das richtige forum ausgewählt habe, hoffe aber ihr könnt mir helfen.
ich bin langsam am Verzweifeln, ich bin gerade dabei einen dartrechner zu schreiben, aber irgendwie haben sich einige grobe fehler eingeschlichen die ich einfach nicht finde.

Das erste problem ist wenn ich ein Spiel mit einer ungeraden Anzahl von Spielern starte, hängt das programm sich auf, wenn man mit dem Debugger das ganze durchklickt läuft er durch allerdings kann ich das neuentstandene Formular trotzdem nicht anwählen.
Das nächste ist das egal mit wievielen Spielern man ein Spiel startet, ich das entstehende Spielformular nich schließen kann weder mit Formular schließen noch mit dem Spiel beenden button.

ich habe erstmal nur die Spielart X01 implementiert.
Nach jedem Spielzug soll derzeit kontrollhalber ein fenster aufgehen wie die züge des Spielers waren. Aber er zeigt immer nur den aktuellen als ersten an darum hatte ich schon mal ins forum gepostet aber der richtige fehler wurde leider nicht gefunden.

Und noch was kleines was aber eher erst mal unwichtig ist, was ich hoffentlich selber finde ist das er manchmal beim spielerwechsel spieler übersprigt, oder jemand doppelt dran ist.

So wäre schön wenn jemand mal ein bischen zeit hätte sich die probleme anzuschauen, weil ich das problem für die schule brauche und mir die zei langsam davon laüft.
Zum testen bitte Spielart x01 auswählen und als würfe bitte E,D oder T und danach eine Zahl oder 0 eingeben


hoffe jemand von euch hat etwas zeit. :lol:

Luckie 12. Jan 2007 13:35

Re: Problem mit Programm
 
Zu deinem Konzept: Das ist nicht gut bzw. ziemlich chaotisch. Un bei den globalen variablen ist es kein Wunder, dass da was durcheinander kommt und du mit dem Debuggen Probleme hast. Ich gucke mal, ob ich hier auf die Schnelle was braucbares für dich hinbekomme.

Der_Unwissende 12. Jan 2007 13:39

Re: Problem mit Programm
 
Hi,
dein Fehler (die Exception beim Beenden) resultiert daraus, dass du die APlayer einfach verwendest (aber nie initialisierst). Da es sich um ein Dyn. Array handelt, wird in dieser Variablen eine Adresse (des eigentlichen Arrays) gespeichert. Da du jetzt einfach auf Elemente einer nicht gültigen Adresse zugreifst, landest du auch irgendwo im Speicher (es ist gar nicht vorhersagbar was wann passiert).

Ansonsten gebe ich Luckie völlig recht, du solltest nochmal über Aufbau und Struktur nachdenken!

Gruß Der Unwissende

[Edit]
Mal als wichtige Ergänzung, ich meinte APlayer in der Unit Game, die Unit Start hab ich nicht weiter betrachtet!
[/edit]

[Edit2]
Und noch eine Anmerkung, wenn du eine eigene Klasse anlegst und einen eigenen Konstruktor verwendest, unbedingt als erste zeile ein inherited create(...); rein!!! (bezieh mich hier auf TPlayer). Ansonsten wird gar kein Speicher für deine Instanz alloziert (wieder ein völlig freier Fehler).
[/Edit2]

Luckie 12. Jan 2007 14:31

Re: Problem mit Programm
 
Liste der Anhänge anzeigen (Anzahl: 1)
Fertig.

Mein Konzept: Es gibt zwei Klassen. Eine verwaltet einen Spieler und die zweite verwaltet die Spielerliste:

Spieler:
Delphi-Quellcode:
  TPlayer = class(TObject)
  private
    FName: String;
    FPunkte: Integer;
    FHasWon: Boolean;
    procedure SetName(Name: String);
    function GetName: String;
    procedure SetPunkte(Punkte: Integer);
    function GetPunkte: Integer;
    function GetHasWon: Boolean;
  public
    property Name: String read GetName write SetName;
    property Punkte: Integer read GetPunkte write SetPunkte;
    property HasWon: Boolean read GetHasWon;
  end;
Spielerliste:
Delphi-Quellcode:
  TPlayerCollection = class(TList)
  private
    function Get(Index: Integer): TPlayer;
  public
    procedure Add(Item: TPlayer);
    function Next(CurrentPlayer: Integer): TPlayer;
    function IndexOf(Item: TPlayer): Integer;
    procedure Free;
    property Items[Index: Integer]: TPlayer read Get;
  end;
Hat man das erstmal, ist die Programmierung kein Problem mehr und reduziert sich auf diese paar Zeilen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  SpielerListe := TPlayerCollection.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SpielerListe.Free;
end;

procedure TForm1.btnNamenClick(Sender: TObject);
var
  i: Integer;
  Spieler: TPlayer;
  NewItem: TListItem;
begin
  for i := 0 to SpinEdit1.Value - 1 do
  begin
    Spieler := TPlayer.Create;
    Spieler.Name := InputBox('Spielername ' + IntToStr(i+1), 'Name des Spilers', IntToStr(i+1));
    Spieler.Punkte := 201;
    SpielerListe.Add(Spieler);
  end;

  for i := 0 to SpielerListe.Count - 1 do
  begin
    NewItem := ListView1.Items.Add;
    NewItem.Caption := Spielerliste.Items[i].Name;
    NewItem.SubItems.Add(IntToStr(Spielerliste.Items[i].Punkte));
  end;
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  CurrentPlayerIdx := 0;
  CurrentPlayer := SpielerListe.Items[CurrentPlayerIdx];
  lblCurrentPlayer.Caption := Format('Spieler: %s', [CurrentPlayer.Name]);
end;

procedure TForm1.btnOKClick(Sender: TObject);
begin
  CurrentPlayer.Punkte := CurrentPlayer.Punkte - sedtFirst.Value - sedtSecond.Value - sedtThird.Value;
  if CurrentPlayer.HasWon then
    ShowMessage(Format('Spieler %s hat gewonnen.', [CurrentPlayer.Name]));
  Listview1.Items[CurrentPlayerIdx].SubItems[0] := IntToStr(CurrentPlayer.Punkte);
  CurrentPlayer := SpielerListe.Next(CurrentPlayerIdx);
  CurrentPlayerIdx := SpielerListe.IndexOf(CurrentPlayer);
  lblCurrentPlayer.Caption := Format('Spieler: %s', [CurrentPlayer.Name]);
end;
Projekt im Anhang.

Nachtrag:
Jetzt könnte man sich noch eine Klasse TGame ausdenken von der man sich weitere Klassen für die verschiedenen Spiele ableitet, die sich dann um die Spielregeln kümmern.

schuetzejanett 12. Jan 2007 16:08

Re: Problem mit Programm
 
Danke schön werde mir dein programm mal zu gemüte führen und dann meins daran anpassen.
Hoffe das meine Probleme dann verschwunden sind.

schönes wochenende

Christian Seehase 12. Jan 2007 18:34

Re: Problem mit Programm
 
Moin Michael,

irgendwie fehlt mir da der Destructor.

Delphi-Quellcode:
procedure TPlayerCollection.Free;
var
  i: Integer;
begin
  for i := 0 to self.Count - 1 do
    self.Items[i].Free;
  // Mindestens
  inherited Free;
end;
wäre besser
Delphi-Quellcode:
TPlayerCollection = class(TList)
//...
public
  destructor Destroy; override;
  // entfällt ersatzlos
  procedure Free;
//...

destructor TPlayerCollection.Destroy;
var
  i: Integer;
begin
  for i := 0 to self.Count - 1 do
    self.Items[i].Free;
  inherited;
end;
Zugegeben, bei TList spielt das keine grosse Rolle, da diese ja direkt von TObject abgeleitet ist, aber so ganz sauber ist es nicht ;-)

Warum eigentlich nicht gleich eine TObjectList?
Da OwnsObjects hier standardmässig auf true steht, würdest Du Dir die Freigabe der Objekte sparen können.

Luckie 12. Jan 2007 22:05

Re: Problem mit Programm
 
Zitat:

Zitat von Christian Seehase
irgendwie fehlt mir da der Destructor.

Mir auch. ;) Ich habe das nur mal eben so zwischen Tür und Angel runtergetippt, dabei ist wohl der Destruktor unten den Tisch gefallen. :oops:

Korrigierte Version hochgeladen.

Luckie 13. Jan 2007 14:34

Re: Problem mit Programm
 
Ich wollte mal fragen, wie du mit meinem Code zurecht kommst.

schuetzejanett 13. Jan 2007 17:29

Re: Problem mit Programm
 
Hallo Luckie,

komme mit deinem code sehr gut zurecht. Danke dafür. Werde mein Spiel mit deinen Klassen nochmal schreiben, und dann versuchen etwas besser zu strukturieren.


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