Autor Beitrag
guitarhero187
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 02.05.10 20:56 
Hallo Leute!

Ich bin momentan die Türme von Hanoi am programieren, und zwar eine grafische Umsetzung (mit Labels). Die Standardversion, von wegen rekursives Denken und bla, läuft einwandfrei.

Da ich jetzt erst seit ca. einem Jahr mit Delphi (schulbedingt Lazarus) arbeite, hatte ich noch nichts mit Arrays zu tun. Ergo habe ich mich erstmal informiert und habe auch so weit alles verstanden.

Nun zum eigentlichen Problem: Bei den Türmen von Hanoi gibt es eine variable Anzahl an Scheiben.
Hier meine Umsetzung mit dynamischen Arrays:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var  //jaja, globale variablen sind unschön, ich weiß
  Form1: TForm1;
  scheibe: array of string;
  ...
  procedure TForm1.Button1Click(Sender: TObject);
  begin
  n:=strtoint(form1.edit1.text);
  runde:=0;
  setlength(scheibe, n);
  ...

Die maximal mögliche Anzahl an Scheiben beträgt bei mir 7, also werden Arrays von scheibe[0] bis scheibe[7] "erstellt".
Die grafische Umsetzung sieht dann so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  ...
  scheibe[7]:='========';
  scheibe[6]:='=======';
  scheibe[5]:='======';
  scheibe[4]:='=====';
  scheibe[3]:='====';
  scheibe[2]:='===';
  scheibe[1]:='=='
  ...

Somit ist die oberste Scheibe scheibe[1].
Wenn Diese (oder die darauf folgenden Scheiben) auf ein anderes Feld gelegt wird, soll der vorherige Platz zu 'II' werden (klappt), und eben der neue Platz statt 'II' zu '==' werden.
Umsetzung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure movetower (n: integer; afromfield, atofield, ausingfield: integer);
begin
  if n > 1 then
    movetower (n - 1, afromfield, ausingfield, atofield);
...
if atofield = 1 then
  begin
    inc(belA);
    tlabel(form1.findcomponent('A' + inttostr(belA))).caption := scheibe[n];
...

Jetzt wird aber das neu besetzte Feld statt '==' zu '========', also dem Wert von scheibe[7].
Ich habe bereits jegliche Kombinationen der Zahlen und Werte ausprobiert, doch es bleibt immer gleich.
Die darauf folgenden Scheiben werden übrigens immer um ein '=' kleiner; das ganz Spiel wird quasi umgekehrt gespielt.

Woran liegt das?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 03.05.10 10:44 
Dynamische Arrays fangen immer mit 0 an. Ein SetLength(A, 7); initialisiert nur Indizes von 0 bis 6.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
guitarhero187 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mo 03.05.10 11:37 
Bei setlength(scheibe, n+1) tritt dasselbe Problem auf.
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 03.05.10 13:39 
user profile iconguitarhero187 hat folgendes geschrieben Zum zitierten Posting springen:
Die maximal mögliche Anzahl an Scheiben beträgt bei mir 7, also werden Arrays von scheibe[0] bis scheibe[7] "erstellt".

Ich denke auch, dass du nicht richtig mit dem Array-Index arbeitest. scheibe[0] bis scheibe[7] sind bei mir 8 scheiben. Schau dir deine Programmlogik nochmal an, ob du nicht irgendwo beim falschen Index anfängst, bzw. aufhörst.
guitarhero187 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mo 03.05.10 16:29 
Ich bin nochmal alles durchgegangen und habe keinen Fehler gefunden... Zumal ich ja schon die Array Zuweisungen z.B. von scheibe[1]:='==' zu scheibe[7]:='==' zur Probe geändert habe, und trotzdem dasselbe Problem auftritt.
Hier einmal der gesamte code, welcher bisher nur für die Eingabe von 7 für n richtig realisiert werden kann (ACHTUNG; mögliche Lösung für Türme von Hanoi rekursiv und grafisch):
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:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    a7: TLabel;
    b1: TLabel;
    b2: TLabel;
    b3: TLabel;
    b4: TLabel;
    b5: TLabel;
    b6: TLabel;
    b7: TLabel;
    c1: TLabel;
    c2: TLabel;
    Label2: TLabel;
    c3: TLabel;
    c4: TLabel;
    c5: TLabel;
    c6: TLabel;
    c7: TLabel;
    Label3: TLabel;
    a1: TLabel;
    a2: TLabel;
    a3: TLabel;
    a4: TLabel;
    a5: TLabel;
    a6: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    ListBox1: TListBox;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end

var
  Form1: TForm1;
  scheibe: array of string;
  belA, belB, belC, n, runde: integer;

implementation


{ TForm1 }

procedure movetower (n: integer; afromfield, atofield, ausingfield: integer);
begin
  if n > 1 then
    movetower (n - 1, afromfield, ausingfield, atofield);

  form1.listbox1.items.add('-> Scheibe ' + inttostr(n) + ' von Feld ' +
            inttostr(afromfield) + ' nach Feld ' + inttostr(atofield));
  inc(runde);

  if afromfield = 1 then
  begin
    tlabel(form1.findcomponent('A' + inttostr(belA))).caption := 'II';
    tlabel(form1.findcomponent('A' + inttostr(belA))).left := 104;
    dec(belA);
  end;

  if afromfield = 2 then
  begin
    tlabel(form1.findcomponent('B' + inttostr(belB))).caption := 'II';
    tlabel(form1.findcomponent('B' + inttostr(belB))).left := 104;
    dec(belB);
  end;

  if afromfield = 3 then
  begin
    tlabel(form1.findcomponent('C' + inttostr(belC))).caption := 'II';
    tlabel(form1.findcomponent('C' + inttostr(belC))).left := 104;
    dec(belC);
  end;

  if atofield = 1 then
  begin
    inc(belA);
    tlabel(form1.findcomponent('A' + inttostr(belA))).caption := scheibe[n];
    tlabel(form1.findcomponent('A' + inttostr(belA))).left := 110 -
      tlabel(form1.findcomponent('A' + inttostr(belA))).width div 2;
  end;

  if atofield = 2 then
  begin
    inc(belB);
    tlabel(form1.findcomponent('B' + inttostr(belB))).caption := scheibe[n];
    tlabel(form1.findcomponent('B' + inttostr(belB))).left := 110 -
      tlabel(form1.findcomponent('B' + inttostr(belB))).width div 2;
  end;

  if atofield = 3 then
  begin
    inc(belC);
    tlabel(form1.findcomponent('C' + inttostr(belC))).caption := scheibe[n];
    tlabel(form1.findcomponent('C' + inttostr(belC))).left := 110 -
      tlabel(form1.findcomponent('C' + inttostr(belC))).width div 2;
  end;

  application.processmessages;
  sleep(strtoint(form1.edit2.text));

  if n > 1 Then
    movetower (n - 1, ausingfield, atofield, afromfield);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  n:=strtoint(form1.edit1.text);
  runde:=0;
  setlength(scheibe, n+1);
  scheibe[7]:='========';
  scheibe[6]:='=======';
  scheibe[5]:='======';
  scheibe[4]:='=====';
  scheibe[3]:='====';
  scheibe[2]:='===';
  scheibe[1]:='==';
  belA:=n;
  belB:=0;
  belC:=0;
  movetower(n, 132);
  form1.listbox1.items.add('Es wurden ' + inttostr(runde) + ' Runden benötigt.');
end;

initialization
  {$I unit1.lrs}

end.