![]() |
Turm von Hanoi
Guten Tag ich muss ein (nicht perfektes) Spiel namens Turm von Hanoi programmieren, am besten mit Klassen , leider habe ich keine Idee wie ich es machen soll ich würde mal paar Ideen schreiben und würde mich für umsetzungen bzw Verbesserungsvorschläge sehr freuen. Ich würde die Klasse Scheiben erstellen, welche ich mit den funktionen positionen und dem Algorythmus des Programms ausstatte und dann noch die Türme damit. bei den scheiben bräuchte ich ein array, damit ich immer weiß wie viele scheiben darauf liegen . Mehr ideen hab ich leider nicht und momentan wüsste ich nicht wie ich diese Klassen dann in die andere unit implementiere. ps ich bin dankbar für alles Lösungsansätze bzw Ideen/Vörschlage:)
|
AW: Turm von Hanoi
Hallo,
ich zeige dir, wie du Klassen grundsätzlich hinbekommst. Danach ist es an dir, falls du weitere Hilfe brauchst, deinen erarbeiteten Code zu zeigen. Noch ein Tipp: mit dem goldenen Helm Icon kannst du einen Code Block ins Forum einfügen. Nehmen wir mal an, du hast eine Form Unit und willst, weil man das sinnvollerweise so macht die eigentliche Spiellogik (Geschäftslogik) in einer separaten Unit mit 1-N Klassen drin umsetzen. Dann klickst du in der Projektverwaltung dein Projekt mit der rechten Maustaste an und wähst "Neue hinzufügen">"Unit". Das erzeugt eine leere Unit. Diese unter einem sinnvollen Namen abspeichern. Du solltest dann sowas wie das haben:
Delphi-Quellcode:
Alles was du in den Interface Abschnitt schreibst kann von anderen Units,
unit HanoiLogik;
interface implementation end. welche diese Unit einbinden (also z.B. dein Hauptformular) aufgerufen werden. Die eigentliche Umsetzung ist dann zwischen Implementation und end. Nun musst du eine Klasse definieren. Deine Unit dürfte dann ca. so aussehen:
Delphi-Quellcode:
So, in diese Klasse baust du alle Felder und Methoden ein die du brauchst um
unit HanoiLogik;
interface type THanoi = class(TObject) private public end; implementation end. die Spiellogik umzusetzen. Was jemand an der Klasse aufrufen können soll, gehört nach public. Hier mal ein bisschen Testcode drin um dir den Aufruf aus dem Hauptformular zu zeigen:
Delphi-Quellcode:
So, nun wollen wir in der MainForm diese Klasse benutzen:
unit HanoiLogik;
interface type THanoi = class(TObject) private FCounter : Integer; public function GetNextCounterValue:Integer; end; implementation function THanoi.GetNextCounterValue:Integer; begin inc(FCounter); Result := Counter; end; end. 1. Die Unit HanoiLogik im Hauptformular einbinden. 2. Ein Feld von dieser Klasse definieren. 3. Ein OnCreate Event in der Form erzeugen (Form Designer!) und dort eine Objektinstanz erzeugen, die in diesem Feld gespeichert wird. 4. Ein OnClose Event in der Form erzeugen und dort die Objektinstanz freigeben. 5. Ein Label auf der Form platzieren. 6. Einen Button und für diesen einen OnClick Handler erstellen. In diesem GetNextCounterValue aufrufen und das Ergebnis auf dem Label anzeigen. Dein Hauptformular dürfte dann ungefähr so aussehen:
Delphi-Quellcode:
So, das sollte einen Start ermöglichen.
Unit Main;
uses [...was auch immer Delphi da hin gepackt hat], HanoiLogik; interface type TMainForm = class(TForm) Label1: TLabel; // möglichst besser benennen Button1: TButton; // dito. procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject); procedure ButtonClick(Sender : TObject); private FHanoiLogic:THanoi; public end; implementation procedure TMainForm.FormCreate(Sender: TObject); begin FHanoiLogic := THanoi.Create; // erzeugt die Objektinstanz end; procedure TMainForm.FormClose(Sender: TObject); begin FHanoiLogic.Free; // Aufräumen bei Programmende end; procedure TMainForm.ButtonClick(Sender : TObject); begin Label1.Caption := IntToStr(FHanoiLogic.GetNextCounterValue); end; Noch eine Frage: Welche Delphi Version benutzt du? Grüße TurboMagic |
AW: Turm von Hanoi
Also Deine Hausaufgabe macht hier niemand aber über Quelltext und fragen darüber können wir gerne sprechen.
Mein Ansatz wäre wahrscheinlich ein sehr einfacher. Hab ein Record das alles bereitstellt was ein "Stab" haben kann, sprich, was kann es empfangen und halten, in deinen fall maximal 3 verschiedene Elemente, die "Scheiben". Lege von diesen Record ein Array an für die Anzahl aller "Stäbe". Gebe dem ersten Array Element alle "Scheiben" in korrekter Reihenfolge. Mehr Logic ist eigentlich nicht von Nöten, Du musst halt nur auswerten welcher "Stab" was bereitstellt, und zwar immer nur das was "oben" liegt, sprich, das letzte element im "Stab-Record". Eine simple "bewege das letzte Element von Stab X nach Stab Y" Logik und eine simple "ist die Reihenfolge in Stab Z korrekt/erreicht" abfrage, mehr braucht man nicht. (Natürlich sollte die Logik auch eine "Existiert überhaupt eine Scheibe im Stab X" Methode bieten um festzustellen ob der gewünschte Spielzug durchgeführt werden kann) Die von mir beschriebe Vorgehensweise kannst Du natürlich in eine Klasse reinprogrammieren die dann zu jedem Zeitpunkt weiß "wo was ist". Der Klasse spendierst Du dann noch eine "Leg los"-Methode die dann die oben genannte Logik durchführt. Wie Du das ganze graphisch umsetzt ist Dir überlassen. Hier mein Einstieg, mach was draus :-D
Delphi-Quellcode:
Type
TDisks = (dNothing, dLarge, dMedium, dSmall); TRod = record Top: TDisks; Middle: TDisks; Bottom: TDisks; end; TRods = array [0..2] of TRod; |
AW: Turm von Hanoi
unit u_HanoiKlasse;
{$mode ObjFPC}{$H+} interface type TTurm= class Scheiben: array [1..n] TTurm Position : integer; uses Classes, SysUtils, Dialogs; implementation { TScheibe } end. kann ich so anfangen um die Klasse zu deklarieren oder ist hier schon ein Fehler und ich würde gerne dann noch eine Funktion erstellen wo es mir die Türme zeichnet |
AW: Turm von Hanoi
Bitte [DELPHI] ... [/DELPHI] um deinen Code drumrum. (der Knopf mit dem Römerhelm)
Was macht das USES in/unter der Klasse? Warum ist die Klassendeklaration nicht abgeschlossen? (end) Was ist n? Ich bin mir fast sicher, dass selbst im Lazarus/FreePascal beim Array das "of" fehlt. Dann fehlt mindestens noch ein ; ... |
AW: Turm von Hanoi
das ist hier eine neue Unit, und sorry nur ich bin leider nicht so gut, ich probiere mich nochmal dran, vielleicht sieht es dann ja noch besser aus.....:cry:
|
AW: Turm von Hanoi
Zitat:
|
AW: Turm von Hanoi
Hat er (sieht man nur nicht, da der CODE-Block fehlt), aber besser wird es nicht wirklich.
Zitat:
Pascal (Delphi) wurde ja mal ursprünglich als "einfachere" Sprache erfunden, um leichter zu lernen, aber ein paar Grundkenntnisse wären angebracht, sie sich vorher zu verinnerlichen, um wenigstens die Syntax erstmal zu verstehen und anwenden zu können. |
AW: Turm von Hanoi
unit u_Turm;
//Julian Lärz {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type { Tfrm_TurmvonHanoi } Tfrm_TurmvonHanoi = class(TForm) btn_starten: TButton; btn_schritt: TButton; btn_schliessen: TButton; Shape1: TShape; procedure btn_schliessenClick(Sender: TObject); procedure btn_startenClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); private public end; var frm_TurmvonHanoi: Tfrm_TurmvonHanoi; vAnzahlscheiben:integer; implementation {$R *.lfm} { Tfrm_TurmvonHanoi } procedure Tfrm_TurmvonHanoi.btn_startenClick(Sender: TObject); var i: Integer; x, y, size: Integer; shape: TShape; begin //zeichnen von Türmen vAnzahlscheiben:= strtoint(Inputbox('Eingabe der Scheiben', 'Gib die Anzahl der Scheiben von Hanoi ein!','')); // Aufruf zum eingeben der zu zeichnenden Scheiben // Setze die Anfangskoordinaten und Größe der Vierecke x := 50; y := 50; size := 30; for i := 1 to vAnzahlscheiben do begin // Erstelle ein neues TShape shape := TShape.Create(Self); shape.Parent := frm_TurmvonHanoi; // Setze die Eigenschaften des TShape shape.Shape := stRectangle; shape.Left := x; shape.Top := y; shape.Width := size; shape.Height := size; shape.Brush.Color := clLime; // Farbe nach Bedarf anpassen // Beschrifte das Viereck mit einem Namen shape.Name := 'Rectangle' + IntToStr(i); shape.Caption := 'Viereck ' + IntToStr(i); // Passe die Koordinaten für das nächste Viereck an x := x + size + 5; end; end; procedure Tfrm_TurmvonHanoi.FormCreate(Sender: TObject); begin end; procedure Tfrm_TurmvonHanoi.FormPaint(Sender: TObject); // in form paint geschrieben, damit keine fehler auftreten und damit ich 2 Ebenen habe und nicht mmeine türme beeinflussen begin Canvas.Brush.Color := clBlue; // Farbe für die Türme Canvas.Pen.Color := clBlack; // Farbe für die Konturen // Erster Turm Canvas.Rectangle(150, 50, 200, 400); // Zweiter Turm Canvas.Rectangle(450, 50, 500, 400); // Dritter Turm Canvas.Rectangle(750, 50, 800, 400); // Erster Turm Canvas.Brush.Color := clWhite; // Farbe für den Text Canvas.TextOut(175, 420, 'A'); // Zweiter Turm Canvas.TextOut(475, 420, 'B'); // Dritter Turm Canvas.TextOut(775, 420, 'C'); end; procedure Tfrm_TurmvonHanoi.btn_schliessenClick(Sender: TObject); begin close; end; end. hier wäre ein neuer quellcode, der erzeugt jetzt immerhin die grafischen sachen, jetzt geht es aber noch um das sortieren und die positionen der shapes, wie könnte ich jetzt hier weiter vorgehen, die andere Variante war mir dann doch leider zu kompliziert |
AW: Turm von Hanoi
Zitat:
|
AW: Turm von Hanoi
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:
Wie stellt man einen Turm dar?
TScheibe = class(TObject)
private FSize: Integer; published property Size: Integer read FSize write FSize; end; 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:
Die eigentliche Spielklasse definiert 3 Türme, Methoden die die Aktionen im Spiel darstellen und den Status des Spiels.
TTurm = class(TObjectList<TScheibe>)
end; (alles ungetestet)
Delphi-Quellcode:
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).
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; Wer das schafft hat sich so viel Hilfe bei den Hausaufgaben verdient und sollte bei der nächsten ähnlichen Aufgabe nicht scheitern. |
AW: Turm von Hanoi
Zitat:
|
AW: Turm von Hanoi
Ja aber so sind wir ihn los.
Wie willst du einem der nichtmal Krabeln kann Stabhochsprung beibringen? Er ist ja auch komplett lern unwillig. Allerdings normalerweise geben wir fertige Lösungen nur an Mädchen, aber Blup ist vermutlich so alt , dass solche unbewusten Wertungen nicht mehr in seine Entscheidungen einfließen. |
AW: Turm von Hanoi
Fertig ist das was Blup geliefert hat nicht. Bei weitem nicht. Steht ja auch so geschrieben.
Ich glaube allerdings auch das Refoxs nur darauf wartet das wir hier aus lauter langer weile Hausaufgaben lösen. |
AW: Turm von Hanoi
Das die Jugend von heute™ nicht Googlen kann, ist schon fast traurig. Das "Problem" ist nach 5 Minuten erledigt.
|
AW: Turm von Hanoi
Zitat:
|
AW: Turm von Hanoi
Das Schlimme ist, dass solche Leute später dann das Abitur bestehen - ohne Eigenleistung und nur durch Pfuschen.
|
AW: Turm von Hanoi
Ich finde es eher schlimm wie manche Leute hier offensichtlich jüngeren Anfängern antworten... Wenn man schon nichts Vernünftiges zur Frage beizusteuern hat, muss man wirklich solch dumme Kommentare stehen lassen? Wir wissen nicht wie sein Kenntnisstand bzgl. Delphi oder Computer allgemein ist und dürfen nicht von jedem erwarten alles einfach schon zu können. Mal ganz davon abgesehen das BB-Codes mittlerweile schon uralte Syntax ist und die Jugend von heute wenn dann nur Markdown kennt...
Delphipraxis ist mittlerweile das einzige deutschsprachige Delphi Forum und wenn man hier auch so blöde angemacht wird, kann ich gut verstehen wieso die heutige Jugend schon gar nicht erst mit Delphi anfangen will... |
AW: Turm von Hanoi
Ich verstehe Euch nicht. Sich hier im Forum anzumelden und Fragen zu stellen, zeigt doch gerade, dass keine fertige Lösung über Google oder eine KI gesucht wurde.
Da kann ich nur unterstreichen, was milos schreibt. Wenn ich als Anfänger so überheblich begrüsst werde, würde ich dem Altherrenclub 8-) auch nicht beitreten wollen. |
AW: Turm von Hanoi
Zitat:
Ganz ehrlich: Ich habe es gerade einfach probiert und der zweite Treffer war eine Lösung in der DP aus dem Jahr 2007. Die anderen Treffer habe ich nicht weiter geprüft, werden aber sicher einige brauchbare dabei gewesen sein. Eine Frage bei der KI liefert eine Lösung auf Basis eines DP-Eintrags von 2010. Ja, ich bin auch ein alter Sack, habe aber schon Anwendungsentwickler ausgebildet in Delphi. Was der TE als Ansatz abliefert, ist Arbeitsverweigerung. Das Thema ist "rekursive Programmierung" und somit kein völliges Anfängerthema! Da erwarte ich, dass grundlegende Kenntnisse vorhanden sind. Die sind hier nicht erkennbar. Betrachtet das mal insgesamt. Keine Eigenleistung (nicht mal danach gesucht), aber am liebsten eine fertige Lösung haben wollen. Dass wir arroganten Altherrenclub-Mitglieder da etwas empfindlich reagieren, ist hoffentlich nachvollziehbar. Jeder der Einsatz zeigt und Eigenleistung bringt, bekommt hier auch Hilfe. Und Vorschläge, wie man mit dem Programm anfängt hat es mehrere gegeben. |
AW: Turm von Hanoi
Zitat:
Dazu kamen auch Antworten, aber eben auch recht schnell das Klischee, dass ein Schüler sich hier von uns die Hausaufgaben machen lassen will. Kann schon sein, aber dafür gäbe es doch tatsächlich ganz andere Möglichkeiten. Einmal googeln und den Quelltext übernehmen, ohne ihn verstanden zu haben. Das nicht zu tun, sondern es schrittweise mit Hilfe aus dem Forum selbst zu versuchen, kann ich doch schlecht zum Vorwurf machen, oder? Gerne zurück zum Thema, falls es noch Fragen gibt. Vielleicht erfahren wir dann ja aus erster Hand, wie die Anfrage gedacht war :) |
AW: Turm von Hanoi
Zitat:
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz