Mit der Darstellung und Steuerung der Anwendung sollte man sich eigentlich erst beschäftigen, wenn man ein fertiges Model der Daten hat.
Das ist aber ein Fehler den jeder Anfänger macht.
Welche Klassen werden benötigt, um jeden Zustand des Spiel darzustellen?
- Scheiben
- Türme
Zusätzlich eine eigene Klasse die Elemente des Spiels uns die fachliche Logik des Spiels zusammne hält.
Dadurch kann man die Darstellung und Steuerung von den Logik und den Methoden des Spiels besser trennen.
- HanoiGame
Welche Eigenschaften hat eine Scheibe?
Für die Grundfunktion des Spiels genügt einfach der Durchmesser im Verhältnis zu anderen Scheiben.
Dafür reicht eine Ganzzahl (z.B. 1 für die kleinste, 2 für die nächst größere, usw.).
Wie groß die eine Scheibe der Größe später gezeichnet wird ist Darstellung, nicht Teil der Spiellogik.
Delphi-Quellcode:
TScheibe = class(TObject)
private
FSize: Integer;
published
property Size: Integer read FSize write FSize;
end;
Wie stellt man einen Turm dar?
Das ist eigentlich nur eine Liste von Scheiben.
Die erste Scheibe liegt ganz unten, die nächste Scheibe darüber, usw. und die letze Scheibe ganz oben.
Delphi-Quellcode:
TTurm = class(TObjectList<TScheibe>)
end;
Die eigentliche Spielklasse definiert 3 Türme, Methoden die die Aktionen im Spiel darstellen und den Status des Spiels.
(alles ungetestet)
Delphi-Quellcode:
THanoiGame = class(TObject)
constructor Create;
destructor Destroy; override;
private
FTurm0: TTurm;
FTurm1: TTurm;
FTurm2: TTurm;
public
{gibt zurück, ob das Spiel erfolgreich beendet wurde, alle Scheiben auf Turm2}
function IsFinished: Boolean;
{bewegt die oberste Scheibe zwischen zwei Türmen}
function Move(AFrom, ATo: TTurm): Boolean;
{ACount gibt die Anzahl der Scheiben an, alle Scheiben auf Turm0}
procedure NewGame(ACount: Integer);
published
property Turm0: TTurm read FTurm0;
property Turm1: TTurm read FTurm1;
property Turm2: TTurm read FTurm2;
end;
implementation
constructor THanoiGame.Create;
begin
inherited;
FTurm0 := TTurm.Create;
FTurm1 := TTurm.Create;
FTurm2 := TTurm.Create;
end;
destructor THanoiGame.Destroy;
begin
inherited;
FTurm0.Free;
FTurm1.Free;
FTurm2.Free;
end;
procedure THanoiGame.NewGame(ACount: Integer);
var
n: Integer;
Item: TScheibe;
begin
FTurm0.Clear;
FTurm1.Clear;
FTurm2.Clear;
for n := ACount downto 1 do
begin
Item := TScheibe.Create;
Item.Size := n;
FTurm0.Add(Item);
end;
end;
function THanoiGame.IsFinished: Boolean;
begin
Result := (FTurm0.Count = 0) and (FTurm1.Count = 0);
end;
function THanoiGame.Move(AFrom, ATo: TTurm): Boolean;
var
Item: TScheibe;
begin
Result := False;
if Assigned(AFrom) and Assigned(ATo) and (AFrom <> ATo) and (AFrom.Count > 0) then
begin
{die oberste Scheibe, muss kleiner sein als die oberste Scheibe des Ziels}
Item := AFrom[AFrom.Count - 1];
if ATo.Count = 0 then
Result := True
else
Result := Item.Size < ATo[To.Count - 1].Size;
if Result then
begin
AFrom.Extract(Item);
ATo.Add(Item);
end;
end;
end;
Was bleibt ist die Klassen zu verstehen, die Spielklasse in der Oberfläche zu erzeugen und darzustellen und auf Eingaben des Spielers zu reagieren (Methoden der Spielklasse aufzurufen).
Wer das schafft hat sich so viel Hilfe bei den Hausaufgaben verdient und sollte bei der nächsten ähnlichen Aufgabe nicht scheitern.