Entwickler-Ecke

Sonstiges (Delphi) - Problem mit Hangman


zuckerpuppe - Do 26.05.11 17:32
Titel: Problem mit Hangman
Hallo,
ich als Delphineuling habe mich durch alle der 59 Fragen bezüglich Delphi auf dieser Seite geklickt, und konnte trotzdem keine Lösung für mein Problem finden:
Ich denke, dass meine Grundidee schon stimmt, nur bleibt das Programm nach dem Drücken einer Taste immer hängen.
Ich hoffe auf erfahrene User, die mir eine schnelle Antwort geben können :)


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:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
unit mGalgenmaennchen;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  THangman = class(TForm)
    laRatenSie: TLabel;
    laRatewort: TLabel;
    imZeichenflaeche: TImage;
    edEingabe: TEdit;
    edFehlversuche: TEdit;
    laFehlversuch: TLabel;
    procedure FormCreate(Suchwort: stringvar Ratewort:string );
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
     i,Fehlversuche: integer;
     Ratewort,Suchwort: string;
     Buchstabe,Zeichen: char;
     function Zufallswort:string;
     procedure Erzeugen (Suchwort: stringvar Ratewort: string);
     function IstVorhanden (Zeichen: char; Wort: string):boolean;
     procedure Ersetzen (Buchstabe: char; Suchwort: stringvar Ratewort: string);
     procedure Zeichnen;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Hangman: THangman;

implementation

function THangman.Zufallswort:string;
var Zahl: integer;
begin
   Zahl := Random (10);
   case Zahl of
        0: Result := 'INFORMATIK';
        1: Result := 'SYLT';
        2: Result := 'SCHLIESSFAECHER';
        3: Result := 'KUTIKULA';
        4: Result := 'TANGENTENSTEIGUNGSFUNKTION';
        5: Result := 'ETHANOLSAEURE';
        6: Result := 'KORBLEGER';
        7: Result := 'AKTIVIERUNGSENERGIE';
        8: Result := 'FINGERHUT';
        9: Result := 'GITARRENSAITE';
   end;
end;

procedure THangman.Erzeugen (Suchwort: stringvar Ratewort: string);
var i: integer;
begin
   //Suchwort := Zufallswort;
   Ratewort := '';
   for i := 1 to Length (Suchwort) do
       Ratewort := Ratewort + '_ ';
end;

procedure THangman.FormKeyPress(Sender: TObject; var Key: Char);
var Zeichen: char;
    Fehlversuche: integer;
begin
   Fehlversuche := 0;
   Zeichen := Upcase(Key);
   edEingabe.Text := Zeichen;
   if IstVorhanden(Zeichen,Suchwort) = True
      then begin
              Ersetzen(Zeichen,Suchwort,Ratewort);
              laRatewort.Caption := Ratewort
            end
      else begin
              Zeichnen;
              Fehlversuche := Fehlversuche + 1;
              //edFehlversuche.Text  := IntToStr (Fehlversuche);
              end
           end;

function THangman.IstVorhanden (Zeichen: char; Wort: string):boolean;
var i: integer;
    Vorhanden: boolean;
begin
   i := 1;
   Vorhanden := False;
   {while (Vorhanden = False) or (i<= Length(Wort)) do
         begin
            if Zeichen = Wort [i]
               then Vorhanden := True;
            i := i+1;
         end;}

repeat
      if Zeichen = Wort[i]
         then Vorhanden := True;
      i := i + 1;
   until (Vorhanden = True) or (i > Length(Wort));
   Result := Vorhanden
end;

procedure THangman.Ersetzen (Buchstabe: char; Suchwort: stringvar Ratewort: string);
var i: integer;
begin
  for i:= 1 to Length (Suchwort) do
       {if Wort [i] = Buchstabe
          then Ratewort[2*i-1]:= Buchstabe;}

          if Buchstabe=Suchwort[i]
             then Ratewort [2*i-1]:=Buchstabe
end;

{$R *.dfm}

procedure THangman.FormCreate(Suchwort: stringvar Ratewort:string );
begin
   i := 0;
   imZeichenflaeche.Canvas.Rectangle(0,0,imZeichenflaeche.Width,imZeichenflaeche.Height);
   //Fehlversuche := 0;
   //edFehlversuche.Text := IntToStr (Fehlversuche);
end;

procedure THangman.Zeichnen;
var Fehlversuche: integer;
begin
   i := i+1;
   with imZeichenflaeche.Canvas do
        case i of
             1begin
                   Pie(40,190,60,210,40,205,60,205);
                   Fehlversuche := Fehlversuche + 1;
                end;
             2begin
                   MoveTo (50,190);
                   LineTo (50,110);
                end;
             3begin
                   MoveTo (50,110);
                   LineTo (90,110);
                end;
             4begin
                   MoveTo (75,110);
                   LineTo (50,130);
                end;
             5begin
                   MoveTo (90,110);
                   LineTo (90,130);
                end;
             6: Ellipse (80,130,100,150);
             7begin
                   MoveTo (90,150);
                   LineTo (90,175);
                end;
             8begin
                   MoveTo (90,175);
                   LineTo (80,185);
                end;
             9begin
                   MoveTo (90,175);
                   LineTo (100,185);
                end;
             10begin
                    MoveTo (90,165);
                    LineTo (80,160);
                 end;
             11begin
                    MoveTo (90,165);
                    LineTo (100,160);
                    ShowMessage('Sie haben verloren!');
                 end;
             end;
end;
end.


Marc. - Do 26.05.11 18:26

Hi und :welcome: im Forum!

Was mir jetzt auf die schnelle aufällt ist, dass mehrmals auf True prüfst. Das ist allerdings falsch.

Ein kleines Beispiel, wann es schief geht:
http://www.delphi-forum.de/viewtopic.php?p=548760#548760
Mehr dazu in der Kategorie Anfängerfehler:
http://www.delphi-treff.de/tutorials/objectpascal/programmierung-mit-boolean-werten/typische-anfaengerfehler/

Grüße


ALF - Do 26.05.11 18:55

Hi und :welcome:

Mich wundert das es überhaupt startet?

Delphi-Quelltext
1:
procedure THangman.FormCreate(Suchwort: stringvar Ratewort:string );                    

Original müsste stehen

Delphi-Quelltext
1:
procedure THangman.FormCreate(Sender: TObject);                    

Von diesem mal abgesehen

Delphi-Quelltext
1:
if IstVorhanden(Zeichen,Suchwort) = True                    

Wo wird 'Suchwort' definiert?

Irgendwie sieht das ganze zusammen kopiert aus oder unkoordiniert geschrieben!?
vielleicht hilft Dir dies http://www.delphi-treff.de/tutorials/ weiter.

Weil die Mängel sind etwas viel!

Gruss ALf


beastofchaos - Do 26.05.11 22:11

Bei solchen Problemen musste halt einfach vorstellen, wie es am Anfang durchläuft bis zu dem Fehler. Erstmal wird die Anwendung erstellst und die From erstellt - wie bereits gesagt:

1. TForm1.FromCreate(Sender: TObject);
2. Die Prozedur durchschaun, was er machen will. Wo er hängt kansnte einfach durchschaun und hoffen, dass du es findest, oder:
Du machst bei FormCreate zwischen jedem Befehl (hier sinds nur 2 Befehle) einmal "ShowMessage('1')" / "...('2')" / etc. Dann sagt er dir nach jedem Befehl so eine Zahl in einem Extra-Fenster.
Angenommen es kommt erst ein Fenster mit "1" und dann die Fehlermeldung. Das heißt direkt vor dem Fenster mit "2" muss der Fehler entstanden sein. Da hast du jetzt einen Prozeduraufruf. Diese
Prozedur arbeiteste einfach auch mit diesem Verfahren grob durch ;) Ein bisschen aufwendig, aber wenn es unverständliche Fehler sind, kannste damit leicht das Problem finden.

Gruß, Thomas


jaenicke - Do 26.05.11 22:39

user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
Du machst bei FormCreate zwischen jedem Befehl (hier sinds nur 2 Befehle) einmal "ShowMessage('1')" / "...('2')" / etc. Dann sagt er dir nach jedem Befehl so eine Zahl in einem Extra-Fenster.
Angenommen es kommt erst ein Fenster mit "1" und dann die Fehlermeldung. Das heißt direkt vor dem Fenster mit "2" muss der Fehler entstanden sein.
So ein Blödsinn, wofür gibt es Debugger? Einfach nen Haltepunkt setzen, zeilenweise durchgehen und schauen was passiert, fertig...
http://www.delphi-treff.de/ueber-delphi/entwicklungsumgebung-bis-delphi-7/debugger/


Narses - Do 26.05.11 22:43

Moin!

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
Du machst bei FormCreate zwischen jedem Befehl (hier sinds nur 2 Befehle) einmal "ShowMessage('1')" / "...('2')" / etc. Dann sagt er dir nach jedem Befehl so eine Zahl in einem Extra-Fenster.
Angenommen es kommt erst ein Fenster mit "1" und dann die Fehlermeldung. Das heißt direkt vor dem Fenster mit "2" muss der Fehler entstanden sein.
So ein Blödsinn, wofür gibt es Debugger?
Wofür es Debugger gibt? Nun, vermutlich für sehr erfahrene Programmierer, die das durchaus nicht einfache Konzept und den Umgang mit so einem komplexen Werkzeug gewohnt sind. :idea: ;)

Sorry Sebastian, aber jemand auf dem Niveau des Quelltextes oben kann mit dem vorgeschlagenen "Debugging" sicher mehr anfangen, als mit einem Debugger. :) Manchmal ist der Weg das Ziel... :D

cu
Narses


jaenicke - Do 26.05.11 22:52

Naja, auswerten usw. mag anfangs zu schwierig sein, aber um nen Haltepunkt zu setzen und durchzugehen um zu schauen wo es hängt, braucht man nun wirklich nicht viele Kenntnisse.


thepaine91 - Fr 27.05.11 08:56

Naja das ist beinahe genau so schwierig wie auf einen Befehl zu klicken und anschließend F1 zu drücken.


jaenicke - Fr 27.05.11 09:19

Oh, ist der Schwierigkeitsgrad doch so hoch? Ok, das geht natürlich nicht.


beastofchaos - Fr 27.05.11 20:30

xD Ok, ich geb zu, dass das aufwendig ist, aber ich hab mir das so angewohnt, weil ich noch nicht mit dem Debugger klar komme. Werd ich gleich mal durch schaun :P


jaenicke - Fr 27.05.11 20:43

Ganz kurz:
Du gehst in die erste Zeile von dem fraglichen Quelltext und drückst F5 um dort einen Haltepunkt zu setzen. Dann führst du das Programm normal in Delphi aus (F9).

Sobald das Programm an der Stelle ankommt, landest du wieder in Delphi. Jetzt kannst du mit F8 zeilenweise durchgehen und schauen wo du landest. Um Endlosschleifen zu finden usw. reicht das im Grunde schon.

Später dann:
Dazu kommen dann noch Sachen wie Auswertung von Variablen. Aber das kommt dann mit der Zeit. Dafür markierst du, während du gerade im Debugger steckst, das Programm also angehalten ist, eine Variable und drückst Strg + F7. Jetzt kannst du deren Wert sehen und auch ändern.
Mit einem Klick auf überwachen landet die in einer Liste und du kannst die beim zeilenweise durchgehen live sehen.

Ich denke nicht, dass das sonderlich kompliziert ist, wenn man immer nur einen speziellen Quelltext anschaut. Also eine Prozedur oder so. Einfach durch das ganze Programm mit dem Debugger gehen usw. ist dann schon deutlich schwieriger. Aber das würde ich auch nie einem Anfänger empfehlen. Mir geht es wirklich vor allem um den ersten Punkt: Einfach mal den Programmablauf in einer Prozedur live verfolgen und dann später auch die Variablen dabei anschauen. ;-)