Autor Beitrag
nairolf92
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 09.02.10 17:20 
user profile iconnairolf92 hat folgendes geschrieben Zum zitierten Posting springen:
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 :D

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
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Di 09.02.10 17:27 
Ja mein Lehrer benutzt immer den Begriff Leinwände :D.
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 09.02.10 17:36 
user profile iconDude566 hat folgendes geschrieben Zum zitierten Posting springen:
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? :P

user profile iconnairolf92 hat folgendes geschrieben Zum zitierten Posting springen:
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.

ausblenden 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)
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Di 09.02.10 18:28 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Danke, habs geschafft ;)
nairolf92 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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:
ausblenden volle Höhe Delphi-Quelltext
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 = 1and (ziel = 2then
  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=1and (ziel=3then
 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=2and (ziel=3then
 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=2and (ziel=1then
 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=3and (ziel=1then
 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=3and (ziel=2then
 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2195

XP
D3Prof, D6Pers.
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 15.02.10 21:18 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Ok, was genau bewirkt OnMouseUp und OnMouseDown?
MaPsTaR
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 90
Erhaltene Danke: 4

Win XP
Delphi 7 Enterprise
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 15.02.10 23:31 
user profile iconMaPsTaR hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 17.02.10 19:19 
so hab die prozedur jetz ein bisschen verändert:
ausblenden volle Höhe Delphi-Quelltext
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..3of timage;
    sa: Array[1..3of 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 167

Win XP, Win Vista
D3 Prof., D7 Pers., Lazarus
BeitragVerfasst: 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.

user profile iconnairolf92 hat folgendes geschrieben Zum zitierten Posting springen:
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...

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 167

Win XP, Win Vista
D3 Prof., D7 Pers., Lazarus
BeitragVerfasst: Do 18.02.10 01:02 
Heyho,

user profile iconnairolf92 hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconnairolf92 hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconnairolf92 hat folgendes geschrieben Zum zitierten Posting springen:

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:
ausblenden 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). ;)