Autor |
Beitrag |
nairolf92
Hält's aus hier
Beiträge: 8
|
Verfasst: Di 09.02.10 16:58
Hallo,
ich soll von der Schule aus das Spiel "Die Türme von Hanoi" programmieren. Als Türme und Scheiben hab ich jeweils Leinwände benutzt. Ich kann auch schon die scheiben bewegen, indem ich die ausgewählte anklicke und dann in ein Edit feld eine Zahl reinschreibe.
Jetzt habe ich aber das Problem, dass ich nicht weiß wie ich schreiben kann, ob ein Turm schon von einer oder zwei Scheibe/n besetzt wurde. In diesem Fall soll die dahin gezogene Scheibe seine top-Position verändern (-32).
Habt ihr Ideen oder Lösungen zu diesem Problem? Wäre euch echt dankbar;)
MfG
Florian
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 09.02.10 17:20
nairolf92 hat folgendes geschrieben : | Als Türme und Scheiben hab ich jeweils Leinwände benutzt. |
Leinwände? Vielleicht steh ich nur grad aufm Schlauch weil mir das passende englische Wort nicht einfällt, dass mir da was sagen würde...*LEO nachguck*...aaah, Canvas ^^ Das sagt mir was
Ok, das Problem ist, so wie ich das verstehe, dass du unten im Stapel was rausnimmst und die andren müssten "runterfallen".
Kannst du mal zeigen, wie du die Scheiben zeichnest?
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: Di 09.02.10 17:27
Ich glaube bei dem Spiel kann man keine Scheiben von unten rausnehmen, nur die Oberste oder?
_________________ Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Di 09.02.10 17:27
Ja mein Lehrer benutzt immer den Begriff Leinwände  .
Nicht ganz. Ich möchte das ich, wenn schon eine Scheibe auf einem Turm liegt, die andere darauf legen können. Bisher ist es aber so, dass sie die andere überdeckt. Ich hab auch schon einen Lösungsansatz aber der funktiniert nicht so wirklich. Hab mal mein Programm angehangen.
Einloggen, um Attachments anzusehen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 09.02.10 17:36
Dude566 hat folgendes geschrieben : | Ich glaube bei dem Spiel kann man keine Scheiben von unten rausnehmen, nur die Oberste oder? |
Jo, das weiß ich auch...ist aber je kein Grund es nicht zu tun, oder?
nairolf92 hat folgendes geschrieben : | Ich möchte das ich, wenn schon eine Scheibe auf einem Turm liegt, die andere darauf legen können. Bisher ist es aber so, dass sie die andere überdeckt. |
Achso, das ist einfach...
Du speicherst einfach, auf welchem Stapel wieviele liegen.
Delphi-Quelltext 1: 2: 3:
| Stapel1ScheibenAnzahl:=3; Stapel2ScheibenAnzahl:=0; Stapel3ScheibenAnzahl:=0; |
Und immer wenn du eine verschiebst, machst du ca so:
(Bsp von Stapel 1 nach 2)
Delphi-Quelltext 1: 2: 3:
| Scheibe1.Top:=x+32*Stapel2ScheibenAnzahl; Stapel2ScheibenAnzahl:=Stapel2ScheibenAnzahl+1; Stapel1ScheibenAnzahl:=Stapel1ScheibenAnzahl-1; |
Hab deinen SourceCode nur mal überflogen, das ist ziemlich wirr eingerückt
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Di 09.02.10 18:28
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Danke, habs geschafft 
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 15.02.10 18:23
So, hab nun erneut ein Problem bei dem ich eure Hilfe benötige.
Ich soll eine Prozedur erstellen, in der ich nur den Anfangs und Endpunkt angeben soll und dann die Scheiben automatisch dahin bewegt werden. Hab schonmal ein Lösungsansatz: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
| procedure bewegen(start,ziel:integer) ; var safe,Auswahl1,Auswahl2,Auswahl3,a,s1a,s2a,s3a:integer; begin s1a := strtoint(edit5.text); s2a := 0; s3a := 0; Auswahl1 :=s1a; Auswahl2 :=s2a; Auswahl3 :=s3a;
if (start = 1) and (ziel = 2) then safe:=12; if safe=12 then begin image(Auswahl1).top := (408-32*s2a); image(Auswahl1).left := image(Auswahl1).left+184; s1a:=s1a-1; s2a:=s2a+1;
end; if (start=1) and (ziel=3) then safe:=13; if safe=13 then begin image(Auswahl1).top := (408-32*s3a); image(Auswahl1).left := image(Auswahl1).left+368; s1a:=s1a-1; s3a:=s3a+1;
if (start=2) and (ziel=3) then safe:=23; if safe=23 then begin image(Auswahl2).top := (408-32*s3a); image(Auswahl2).left := image(Auswahl2).left+184; s2a:=s2a-1; s3a:=s3a+1;
if (start=2) and (ziel=1) then safe:=21; if safe=21 then begin image(Auswahl2).top := (408-32*s1a); image(Auswahl2).left := image(Auswahl2).left-184; s2a:=s1a-1; s1a:=s1a+1;
if (start=3) and (ziel=1) then safe:=31; if safe=31 then begin image(Auswahl).top := (408-32*s1a); image(Auswahl).left := image(Auswahl).left-368; s3a:=s3a-1; s1a:=s1a+1;
if (start=3) and (ziel=2) then safe:=32; if safe=32 then begin image(Auswah)l.top := (408-32*s1a); image(Auswahl).left := image(Auswahl).left-184; s3a:=s3a-1; s2a:=s2a+1; end; |
die zahlen (bei start und ziel stehen für die türme, s1a soll Stapel1Anzahl heißen, also die Anzahl der Scheiben die auf Stapel 1 liegen und edit5 ist das feld in den man diese Anzahl von 1-8 festlegen kann). Ich merke grad, dass die variable safe unnütz ist, aber abgesehen davon zeigt er noch ziemlich viele fehlermeldungen an.
darf man bei einer prozedur nicht auf die edit- und image felder zurückgreifen? wenn ja wie könnte ich es anders schreiben?
|
|
Blackheart666
      
Beiträge: 2195
XP
D3Prof, D6Pers.
|
Verfasst: Mo 15.02.10 18:27
Gib doch beim nächsten mal den Crosspost mit an
www.delphipraxis.net...uerme+von+hanoi.html
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Mo 15.02.10 18:57
Also auf jeden Fall solltest du deinen Code besser einrücken, so ist es total unleserlich. Und ich glaube auch, dass es für dich einfacher sein würde, wenn du folgendes Konzept verwendest (so habe ich das mal relativ schnell geschafft):
- nimm ein array of TColor und speichere Farben für jede Scheibe ab.
- nimm eine Zeichenfläche und male darauf die Scheiben mit Canvas.Ellipse
- dann musst du nur noch Start- und Zielstapel bei OnMouseUp und OnMouseDown abfragen und verschiebst nur die oberste Scheibe.
So hat man am wenigsten Code, schafft es schön schnell und sauber und es ist gewährleistet, dass die Regeln eingehalten werden.
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 15.02.10 21:18
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Ok, was genau bewirkt OnMouseUp und OnMouseDown?
|
|
MaPsTaR
      
Beiträge: 90
Erhaltene Danke: 4
Win XP
Delphi 7 Enterprise
|
Verfasst: Mo 15.02.10 21:30
OnMouseDown wird aufgerufen, wenn du, auf dem Objekt, die Maustaste drückst.
OnMouseUp wird aufgerufen, wenn du die Maustaste wieder loslässt.
_________________ Liebe Kinder, es stimmt ... solnage auch nur der ertse und lezte Bchutsabe rihctig ist und alle andreen Bcuhsatben irgendwie vorahnden sind,
dann knan man es dennonch lesen, also macht nur weiter so, wir verstehen euch schon
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 15.02.10 23:31
MaPsTaR hat folgendes geschrieben : | OnMouseDown wird aufgerufen, wenn du, auf dem Objekt, die Maustaste drückst.
OnMouseUp wird aufgerufen, wenn du die Maustaste wieder loslässt. |
Ach so, dann hilft mir der Vorschlag von Jakob leider nicht weiter, da ich eine Prozedur programmieren soll, die ich in einer anderen verwenden kann, d.h. sie muss ohne Interaktionen auf dem Feld auskommen.
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 17.02.10 19:19
so hab die prozedur jetz ein bisschen verändert:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75:
| var Scheibenbild: Array [1..8,1..3] of timage; sa: Array[1..3] of integer;
procedure TForm1.FormCreate(Sender: TObject); var n : integer; begin
For n := 1 to 8 do Begin sa[1] := n; sa[2] := 0; sa[3] := 0; end;
Scheibenbild[1,1] := Scheibe4; Scheibenbild[2,1] := Scheibe5; Scheibenbild[3,1] := Scheibe6; Scheibenbild[4,1] := Scheibe7; Scheibenbild[5,1] := Scheibe8; Scheibenbild[6,1] := Scheibe9; Scheibenbild[7,1] := Scheibe10; Scheibenbild[8,1] := Scheibe11;
end; procedure bewegen(start,ziel:boolean); var a,q,s:boolean; begin
if ((start=q) and (ziel=a)) then begin Scheibenbild[sa[1],1].top := (408-32*sa[2]); Scheibenbild[sa[1],1].left := Scheibenbild[sa[1],1].left+184; sa[1]:=sa[1]-1; sa[2]:=sa[2]+1; end;
if (start=q) and (ziel=s) then begin Scheibenbild[sa[1],1].top := (408-32*sa[3]); Scheibenbild[sa[1],1].left := Scheibenbild[sa[1],1].left+184; sa[1]:=sa[1]-1; sa[3]:=sa[3]+1; end;
if (start=a) and (ziel=s) then begin Scheibenbild[sa[2],1].top := (408-32*sa[3]); Scheibenbild[sa[2],1].left := Scheibenbild[sa[2],1].left+184; sa[2]:=sa[2]-1; sa[3]:=sa[3]+1; end;
if (start=a) and (ziel=q) then begin Scheibenbild[sa[2],1].top := (408-32*sa[1]); Scheibenbild[sa[2],1].left := Scheibenbild[sa[2],1].left+184; sa[2]:=sa[2]-1; sa[1]:=sa[1]+1; end;
if (start=s) and (ziel=q) then begin Scheibenbild[sa[3],1].top := (408-32*sa[1]); Scheibenbild[sa[3],1].left := Scheibenbild[sa[3],1].left+184; sa[3]:=sa[3]-1; sa[1]:=sa[1]+1; end;
if (start=s) and (ziel=a) then begin Scheibenbild[sa[3],1].top := (408-32*sa[2]); Scheibenbild[sa[3],1].left := Scheibenbild[sa[3],1].left+184; sa[3]:=sa[3]-1; sa[2]:=sa[2]+1; end;
end; |
tatsächlich zeigt er bei der prozedur keinen fehler mehr an, jedoch wenn ich diese mit "bewegen(q,a)" auf einem button abrufen will. Die Fehlermeldung sagt: Operator oder Simikolon fehlt.
was könnte der fehler sein? ist es falsch mit z.b. if (start=s) and (ziel=a) then anzufangen?
|
|
COMMANDER86
      
Beiträge: 167
Win XP, Win Vista
D3 Prof., D7 Pers., Lazarus
|
Verfasst: Mi 17.02.10 21:46
Moin,
also ich muss gestehen, dass ich das Spiel jetzt nicht wirklich kenne, aber ich verstehe schon nicht, was Du da vorhast.
1. Warum übergibst Du der Prozedur Start und Ziel als boolean?
2. In der Prozedur vergleichst Du mit den drei Variablen a, q und s in diversen Kombinationen. Das sind lokale Variablen und die Wertzuweisung habe ich nicht wirklich gefunden. Sprich: a, q und s haben immer den Default-Wert. Ohne eine Zuweisung sind die recht... sinnfrei an der Stelle.
3.
nairolf92 hat folgendes geschrieben : | tatsächlich zeigt er bei der prozedur keinen fehler mehr an, jedoch wenn ich diese mit "bewegen(q,a)" auf einem button abrufen will. Die Fehlermeldung sagt: Operator oder Simikolon fehlt.
|
Die Fehlermeldung kommt bei der Zeile in der Prozedur des Buttons? In dem Codeteil sehe ich nun keinen solchen Fehler. Hm...
Delphi-Quelltext 1: 2: 3: 4:
| procedure Button1Click(Sender: TObject); begin bewegen(True, False); end; |
Das sollte für den Aufruf ja genügen.
Zitat: | ist es falsch mit z.b. if (start=s) and (ziel=a) then anzufangen? |
Nein, eigentlich nicht. Kannste halten wie ein Dachdecker. Ich sehe bloß den Sinn (s.o.) nicht in diesen Vergleichen.
_________________ Streichen Sie bitte sämtlichen Sarkasmus aus vorhergehender Nachricht. Dann wissen Sie, was ich sagen möchte. Meine Lösungen sind die vermutlich Umständlichsten, aber sie funktionieren (bei mir).
|
|
nairolf92 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 18.02.10 00:27
die prozedur soll bewirken dass jenachdem welchen buchstaben dieser 3 ich hinschreibe eine timage scheibe von dem einen turm zum anderen bewegt werden soll. D.h. q steht für den Turm Quelle, a für abeitsbereich und s für senke. ich dachte man kann dann wenn man die prozedur aufrufen will z.b. mit "bewegen(q,s)" bewirken, dass eine scheibe von der quelle zur senke bewegt wird. und dafür reicht true und false nicht aus.
deshalb auch " if start=q and ziel=s then: damit wollte ich sagen, dass wenn der 1. buchstabe in der klammer q ist und der 2. s dann soll eine scheibe von der quelle zur senke bewegt werden.
|
|
COMMANDER86
      
Beiträge: 167
Win XP, Win Vista
D3 Prof., D7 Pers., Lazarus
|
Verfasst: Do 18.02.10 01:02
Heyho,
nairolf92 hat folgendes geschrieben : | die prozedur soll bewirken dass jenachdem welchen buchstaben dieser 3 ich hinschreibe eine timage scheibe von dem einen turm zum anderen bewegt werden soll. D.h. q steht für den Turm Quelle, a für abeitsbereich und s für senke. |
also... das Spielprinzip werde ich mir mal anschauen müssen.
nairolf92 hat folgendes geschrieben : | ich dachte man kann dann wenn man die prozedur aufrufen will z.b. mit "bewegen(q,s)" bewirken, dass eine scheibe von der quelle zur senke bewegt wird. und dafür reicht true und false nicht aus. |
Okay, wie gesagt, ich habe mich mit dem Spiel an sich noch nicht beschäftigt. Boolean ist ja aber dann der falsche Datentyp; der kann nur True und False. Da Du die Prozedur ja ohnehin ausgelagert hast, würde ich hier drei Variablen übergeben: WAS muss von WO WOHIN. Die schnellste Lösung wäre es wohl, die Dinger als Strings zu übergeben. Macht den Quelltext was lesbarer, aber geht sicherlich auch schicker. Was adäquates fällt mir da ad hoc aber nicht ein.
nairolf92 hat folgendes geschrieben : |
deshalb auch " if start=q and ziel=s then: damit wollte ich sagen, dass wenn der 1. buchstabe in der klammer q ist und der 2. s dann soll eine scheibe von der quelle zur senke bewegt werden. |
Wenn Du Strings als Variablen verwendet, dass kannst Du das schon fast so stehen lassen:
Delphi-Quelltext 1: 2:
| if (start = 'q') and (ziel = 's') then |
LG
Fabian
_________________ Streichen Sie bitte sämtlichen Sarkasmus aus vorhergehender Nachricht. Dann wissen Sie, was ich sagen möchte. Meine Lösungen sind die vermutlich Umständlichsten, aber sie funktionieren (bei mir).
|
|
|