AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Turm von Hanoi

Ein Thema von Revoks · begonnen am 7. Mär 2024 · letzter Beitrag vom 13. Mär 2024
Antwort Antwort
Seite 1 von 2  1 2      
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.034 Beiträge
 
Delphi 12 Athens
 
#1

AW: Turm von Hanoi

  Alt 7. Mär 2024, 21:52
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:
unit HanoiLogik;

interface

implementation

end.
Alles was du in den Interface Abschnitt schreibst kann von anderen Units,
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:
unit HanoiLogik;

interface

type
  THanoi = class(TObject)
  private
  public
  end;

implementation

end.
So, in diese Klasse baust du alle Felder und Methoden ein die du brauchst um
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:
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.
So, nun wollen wir in der MainForm diese Klasse benutzen:

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:
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;
So, das sollte einen Start ermöglichen.

Noch eine Frage: Welche Delphi Version benutzt du?

Grüße
TurboMagic
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Turm von Hanoi

  Alt 8. Mär 2024, 01:26
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
Delphi-Quellcode:
Type
  TDisks = (dNothing, dLarge, dMedium, dSmall);
  TRod = record
    Top: TDisks;
    Middle: TDisks;
    Bottom: TDisks;
  end;
  TRods = array [0..2] of TRod;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Revoks

Registriert seit: 7. Mär 2024
 
#3

AW: Turm von Hanoi

  Alt 8. Mär 2024, 15:06
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#4

AW: Turm von Hanoi

  Alt 8. Mär 2024, 15:24
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 ;
...
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 8. Mär 2024 um 16:43 Uhr)
  Mit Zitat antworten Zitat
Revoks

Registriert seit: 7. Mär 2024
 
#5

AW: Turm von Hanoi

  Alt 8. Mär 2024, 15:30
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.....
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#6

AW: Turm von Hanoi

  Alt 8. Mär 2024, 15:56
Zitat:
sorry nur ich bin leider nicht so gut
Als erstes würde es schon helfen, den Code nicht einfach stumpf runterzuschreiben wie es gefühlt 8 von 10 Schülern machen sondernden auch einzurücken.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#7

AW: Turm von Hanoi

  Alt 8. Mär 2024, 16:42
Hat er (sieht man nur nicht, da der CODE-Block fehlt), aber besser wird es nicht wirklich.
Delphi-Quellcode:
unit u_HanoiKlasse;

{$mode ObjFPC}{$H+}

interface
type
    TTurm= class
   Scheiben: array [1..n] TTurm
    Position : integer;
uses
  Classes, SysUtils, Dialogs;




implementation

{ TScheibe }




end.
Wenn schon dann richtig halbwegs vernünftig einzurücken.


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.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 8. Mär 2024 um 16:45 Uhr)
  Mit Zitat antworten Zitat
Revoks

Registriert seit: 7. Mär 2024
 
#8

AW: Turm von Hanoi

  Alt 8. Mär 2024, 17:00
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
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#9

AW: Turm von Hanoi

  Alt 8. Mär 2024, 17:25
Zitat:
hier wäre ein neuer quellcode
Den wird sich keiner freiwillig ansehen. Schon mehrfach wurde erwähnt doch bitte Delphi-Code-Tags zu nutzen.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#10

AW: Turm von Hanoi

  Alt 11. Mär 2024, 15:50
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.

Geändert von Blup (11. Mär 2024 um 16:12 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:18 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