Entwickler-Ecke

Multimedia / Grafik - Galgenmännchen / Hangman / Galgenraten


-delphin- - Do 22.09.05 17:52
Titel: Galgenmännchen / Hangman / Galgenraten
Hallo Forum,
ich progge grade Galgenmännchen, würde es zumindest gerne.
Bisher sucht sich das Programm ein Wort aus einer Liste in einem Memo aus und schreibt es in ein nicht sichtbares Editfeld. Was mir noch fehlt ist das Galgenmännchen, welches allerdings am Ende kommt und die Ausgabe der "Striche", also des gesuchten Wortes, bei was ich nicht weiß, wie ich es machen soll.
Momentan würde ich erstmal gerne das Wort in Chars aufteilen und abfragen, ob der Buchstabe im Wort ist.

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:
var
  Form1: TForm1;
  word: string;
  Zufall: integer;
  Wort: array [1..12of char;

implementation

{$R *.dfm}

procedure TForm1.BStartClick(Sender: TObject);
begin
  CreateWord;
  Edit1.Text:=word;
  Zerlegewort;
end;

procedure TForm1.CreateWord;
begin
  Zufall:=random(MWordlist.Lines.Count)+1;
  case Zufall of
  1..1000: word:=MWordlist.Lines.Strings[Zufall];
  end;
end;

procedure TForm1.Zerlegewort;
var i, Laenge: integer;
begin
  Laenge:=Length(word);
  for i:=1 to Laenge do begin
    word[i]:=Wort[i];
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Rate: string;
    i: integer;
begin
  Rate:=EBuchstabe.Text;
  for i:=1 to 12 do
  if Rate=Wort[i] then
  //Buchstabe ist im Wort
  else
  //...ist nicht im Wort
  EBuchstabe.Text:='';
  EGeraten.Text:=EGeraten.Text+Rate+', ';
end;

end.


starsurfer - Do 22.09.05 17:59

einfach wärs ud lässt das wort zusammen und machst das:

Delphi-Quelltext
1:
if pos(buchstabe,wort)=0 then showmessage('Buchstabe ist nicht drinne');                    


-delphin- - Do 22.09.05 21:53

Jetz habe ich ein Editfeld, welches pro Buchstabe ein '_' erzeugt. Wenn jetzt der Buchstabe im Wort ist, müsste er mir den Unterstrich, welcher an der Stelle steht, durch den Buchstaben (bei mir unter Rate gespeichert) ersetzen.
ALlerdings brauch ich dafür einen Befehl, mit dem man die einzelnen Chars in nem Editfeld ansprechen kann, also sowas:
EWort.Text[pos(rate,wort)]:=Rate. Da ist wohl aber der Wunsch der Vater des Gedankens ;)
Thx 4 help


Blackheart666 - Do 22.09.05 22:19

Weil die Frage schon öfter kam (Hangman) bei Delphi3 ist das mit dabei als Demo. Siehe Anhang musst Du noch etwas abändern aber Ich schätze mal das wird Dir schon etws weiter helfen.

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:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
unit Hangy;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, Menus, ExtCtrls, StdCtrls;

type
  THangMan = class (TObject)
  private
    OK, Nr, Laenge, Max: integer;
    Fertig, Mimik: boolean;
    RateText, Geraten: String;
    Liste: TStringList;
    procedure SetZero;
  public
    procedure ClearHangMan; virtual;
    procedure DrawHangMan; virtual;
    procedure ShowHangMan; virtual;
    procedure GetKey (Key: char); virtual;
    procedure GetList (Datei: String); virtual;
    constructor Create (Datei: String);
    destructor Free; virtual;
  end;

type
  TForm1 = class(TForm)
    ReadyButton: TButton;
    NewButton: TButton;
    Panel1: TPanel;
    Panel2: TPanel;
    Image1: TImage;
    Label1: TLabel;
    MainMenu1: TMainMenu;
    Datei1: TMenuItem;
    Oeffnen1: TMenuItem;
    Ende1: TMenuItem;
    OpenDialog1: TOpenDialog;
    procedure NewButtonClick(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: char);
    procedure ReadyButtonClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Oeffnen1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Ende1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const Pfad = 'c:\delphi\buch\';
var
  HangMan: THangMan;
  Form1: TForm1;

implementation

{$R *.DFM}

constructor THangMan.Create (Datei: String);
begin
  Liste := TStringList.Create;
  SetZero;
  Mimik := true;
  try
  // noch nicht ok!
    If FileExists(Datei) Then
    begin
      Liste.LoadFromFile (Datei);
      Max := Liste.Count;
    end;
  except
    on EFOpenError do
    begin
      Form1.Panel1.Caption := 'Ohne Worte!';
      Max := 0;
    end;
  end;
end;

destructor THangMan.Free;
begin
  Liste.Clear;
  Liste.Free;
end;

procedure THangMan.SetZero;
begin
  Geraten := '';
  Nr := 0;
  OK := 0;
  Fertig := false;
  Form1.Image1.Canvas.Brush.Color := clGray;
  Form1.Image1.Canvas.Rectangle(0,0,140,200);
end;

procedure THangMan.ClearHangMan;
var i: integer;
begin
  SetZero;
  if Max > 0 then RateText := UpperCase(Liste.Strings[random(Max)])
  else RateText := UpperCase('Delphi');
  Laenge := Length(RateText);
  for i:=0 to Laenge-1 do
  begin
    Geraten := Geraten + '?';
  end;
  Form1.Panel1.Caption := Geraten;
  Form1.Label1.Caption := 'Buchstaben eintippen!';
end;

procedure THangMan.ShowHangMan;
var Mix: integer;
begin
  Mix := 10;
  if Mimik then Mix := 11;
  Nr := 0;
  while Nr < Mix do begin inc(Nr); DrawHangMan; end;
  Form1.Panel1.Caption := RateText;
  if RateText = '' then
    Form1.Label1.Caption := 'Da ist kein Wort'
  else
    Form1.Label1.Caption := 'ist das Wort';
  Mimik := not(Mimik);
end;

procedure THangMan.DrawHangMan;
begin
  Form1.Image1.Canvas.Pen.Width := 3;
  Form1.Image1.Canvas.Brush.Color := clSilver;
  case Nr of
    1:
    begin
      Form1.Image1.Canvas.MoveTo (30,10);
      Form1.Image1.Canvas.LineTo (30,200);
    end;
    2:
    begin
      Form1.Image1.Canvas.MoveTo (30,10);
      Form1.Image1.Canvas.LineTo (95,10);
    end;
    3:
    begin
      Form1.Image1.Canvas.MoveTo (95,10);
      Form1.Image1.Canvas.LineTo (95,30);
    end;
    4:
    begin
      Form1.Image1.Canvas.Brush.Color := clRed;
      Form1.Image1.Canvas.Ellipse (80,30,110,65);
    end;
    5:
    begin
      Form1.Image1.Canvas.Ellipse (80,65,110,130);
    end;
    6:
    begin
      Form1.Image1.Canvas.MoveTo (90,130);
      Form1.Image1.Canvas.LineTo (90,170);
    end;
    7:
    begin
      Form1.Image1.Canvas.MoveTo (100,130);
      Form1.Image1.Canvas.LineTo (100,170);
    end;
    8:
    begin
      Form1.Image1.Canvas.Ellipse (75,165,95,175);
    end;
    9:
    begin
      Form1.Image1.Canvas.Ellipse (95,165,115,175);
    end;
    10:
    begin
      Form1.Image1.Canvas.Brush.Color := clAqua;
      Form1.Image1.Canvas.Ellipse (80,30,110,65);
      Form1.Image1.Canvas.Brush.Color := clYellow;
      Form1.Image1.Canvas.Ellipse (86,38,95,48);
      Form1.Image1.Canvas.Ellipse (95,38,104,48);
      Form1.Image1.Canvas.Arc (86,54,104,60,104,57,86,57);
    end;
    11:
    begin
      Form1.Image1.Canvas.Brush.Color := clFuchsia;
      Form1.Image1.Canvas.Ellipse (80,30,110,65);
      Form1.Image1.Canvas.Brush.Color := clLime;
      Form1.Image1.Canvas.Ellipse (86,38,95,48);
      Form1.Image1.Canvas.Ellipse (95,38,104,48);
      Form1.Image1.Canvas.Arc (86,45,104,60,86,53,104,53);
    end;
  end;
end;

procedure THangMan.GetKey (Key: char);
var Taste: String; Enthalten: boolean; i: integer;
begin
  Taste := UpperCase(Key);
  Enthalten := false;
  if not(Fertig) then
  begin
    {Jeden Buchstaben einzeln überprüfen}
    for i:=1 to Laenge do
    begin
      if (Taste = copy (RateText,i,1)) then
      begin
        if (Taste <> copy (Geraten,i,1)) then
        begin
          inc (OK);
          Geraten[i] := Key;
          Geraten := UpperCase(Geraten);
        end;
        Enthalten := true;
      end;
    end;
    {Wenn Key enthalten, anzeigen}
    if Enthalten then
      Form1.Panel1.Caption := Geraten
    {sonst Hangman weiterzeichnen}
    else
    begin
      inc (Nr);
      if (Nr < 11then DrawHangMan;
    end;
    {Wenn alle Buchstaben geraten, OK}
    if (OK >= Laenge) and (Nr < 10then
    begin
      if RateText = '' then
        Form1.Label1.Caption := 'Klick auf NEU!'
      else
        Form1.Label1.Caption := 'OK';
      SetZero;
      Fertig := true;
      Form1.Image1.Picture.LoadFromFile ('HangMan.bmp');
    end
    {Wenn Hangman vollständig, TOT}
    else if (Nr >= 10and (not Fertig) then
    begin
      Form1.Panel1.Caption := RateText;
      Form1.Label1.Caption := 'TOT';
    end;
  end;
end;

procedure THangMan.GetList (Datei: String);
begin
  SetZero;
  try
  begin
    Liste.LoadFromFile (Datei);
    Max := Liste.Count;
  end;
  except
    Form1.Panel1.Caption := 'Ohne Worte!';
    Max := 0;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
  HangMan := THangMan.Create (Pfad+'HangMan.txt');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  {HangMan.Free;}
end;

procedure TForm1.NewButtonClick(Sender: TObject);
begin
  HangMan.ClearHangMan;
end;

procedure TForm1.ReadyButtonClick(Sender: TObject);
begin
  Form1.Image1.Canvas.Brush.Color := clGray;
  Form1.Image1.Canvas.Rectangle(0,0,140,200);
  HangMan.ShowHangMan;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin
  HangMan.GetKey (Key);
end;

procedure TForm1.Oeffnen1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    HangMan.GetList (OpenDialog1.FileName);
end;

procedure TForm1.Ende1Click(Sender: TObject);
begin
  Close;
end;

end.


-delphin- - Fr 23.09.05 15:07

hm ich wollte eigentlich nicht den ganzen quelltext sondern nur den Befehl der ein einziges Zeichen in einem editfeld anspricht. außerdem hast du glaub ich ein anderes verfahren als ich.


Blackheart666 - Fr 23.09.05 16:22

Das sollte ja auch nur ein Anstoß sein, das man die Sache viel einfacher lösen kann.
Wenns Dir ums Prinzip geht musst du natürlich deine Fragen dementsprechend stellen.


-delphin- - Fr 23.09.05 20:01

hm.. trotzdem die frage, ob man in einem string einzelne chars ansprechen kann und diese auch ersetzen kann und wenn ja, wie :D


Lannes - Sa 24.09.05 00:05

Hallo,
user profile icon-delphin- hat folgendes geschrieben:
... sondern nur den Befehl der ein einziges Zeichen in einem editfeld anspricht...
... in einem string einzelne chars ansprechen kann und diese auch ersetzen kann ...

in einem String kannst Du einzelne Chars ersetzen:

Delphi-Quelltext
1:
2:
3:
  sSuch := 'Delphi';
  sAusg := '------';
  sAusg[2] := 'e';// >> '-e----'


direkt in einem Edit geht das nicht,
aber den String kannst Du ja anschließend zuweisen:

Delphi-Quelltext
1:
  Edit1.Text := sAusg;                    


-delphin- - So 25.09.05 11:45


Delphi-Quelltext
1:
2:
3:
  Ausgabe := EWort.Text;
  Ausgabe[Position]:=Letter;
  EWort.Text := Ausgabe;


Letter ist eine Variable vom Typ Char, Ausgabe von String. Problem ist, dass er, wenn z.B. das Wort 'Handschuh' ist und man rät ein 'd' (gespeichert in Letter), dann macht er statt '---d-----' nur noch '---', bricht also ab, sobald die Änderung kommt


Lannes - So 25.09.05 19:55

Hallo,

überprüf mal was zu dem Zeitpunkt in Letter steht.

Nur mit den drei Zeilen kann man wenig sagen, da der Zusammenhang zum restlichen Code nicht ersichtlich ist.


-delphin- - Mo 26.09.05 21:22

Letter ist zu dem Zeitpunkt leer...
Ich brauch noch die Funktion, die mir ne Char-Variable speichert, d.h. ich geb z.b. in nem editfeld mit maxlength 1 ein A und dann ist der Char ein A, bisher hatte ich da Letter := EBuchstabe.PasswordChar;, .Text geht ja nicht wegen Char-Variable


Amateur - Mo 26.09.05 21:50

also :
edit1.text speicherste als string z.b. meintext. dann kannste mit meintext[1] z.b. den ersten buchstaben aus dem string also aus edit1.text ansprechen. damit sollte das ganze ziemlich einfach sein


Lannes - Di 27.09.05 00:06

Hallo,
user profile icon-delphin- hat folgendes geschrieben:
[delphi]...Problem ist, dass er, wenn z.B. das Wort 'Handschuh' ist und man rät ein 'd' (gespeichert in Letter...
user profile icon-delphin- hat folgendes geschrieben:
...Letter ist zu dem Zeitpunkt leer...

Leer oder #0 :gruebel:
Vermute das Du Letter irgendwie nicht richtig setzt.
Also bleibt meine Feststellung bestehen:
Nur mit den drei Zeilen kann man wenig sagen, da der Zusammenhang zum restlichen Code nicht ersichtlich ist.