Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zahlen Rätsel Zeitangabe und Neustarten


Blubba - Mo 20.02.12 11:56
Titel: Zahlen Rätsel Zeitangabe und Neustarten
Ich habe Versucht ein zahlen Rätsel zu machen wollte aber noch das auf einem Label eine Zeit angezeigt wird wie lange das Spiel schon geht. Und wie kann ich einfügen, dass der Neustart das Neustartet welcher Schwierigkeitsgrad gewählt ist. Er Setzt dann nur die die Labels zurück aber die Versuche bleiben gleich. Vorher hatte ich das er immer den Einfachen Modus startet.

Mfg Der Blubb
danke im Voraus


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:
procedure TForm1.FormCreate(Sender: TObject);                                   //Denkt sich eine Zahl und anzahl der Versuche
begin
  Randomize;
  Wurfel  := Random(101);
  Versuch := 7;
end;

procedure TForm1.bTestenClick(Sender: TObject);
begin
  Zahl              := StrtoInt(edEingabe.Text);                                //Übernimmt den eingegeben Wert als String
  Versuch           := Versuch-1;                                               //Ein Versuch weniger beim klick
  lBeginnen.Caption := ' ';                                                     //Setzt den Text auf Leer der nach einer Partie kommt
  Ergebnis          := Versuch;                                               //Ist dazu da das man am ende nicht einfach weiter spielen kann
    if Versuch > 0 then
      begin
      lVersuche.Caption   := 'Sie haben noch ' +InttoStr(Versuch)+' Versuche.'//Wenn noch mehr als 0 Versuche da sind gibt es die Versuche aus.
      end;
    if Versuch = 0 then
      begin
        lVersuche.Caption := 'Sie haben Leider keine Versuche mehr';            //Wenn keine Versuche übrig sind, dann gibt es den Text aus
      end;
    if Versuch < 0 then
      begin
        ShowMessage('Verstehen sie nicht. Sie haben keine Versuche mehr');      //Wenn man weiterversucht gibt es ein Popup
        ShowMessage('Die Zahl war ' +InttoStr(Wurfel));                         //Verrät die zahl
      end;
    if Zahl > Wurfel then
      begin
       lAusgabe.Caption   := 'Die Zahl ist leider zu groß!';                    //Hinweis
      end;
    if Zahl < Wurfel then
      begin
        lAusgabe.Caption  := 'Die Zahl ist leider zu klein!';                   //Hinweis
      end;
    if  (Zahl = Wurfel)                                                         //Treffer
    And (Ergebnis >= 0 ) then                                                    //Nur wenn Versuche auf 0 oder höher stehen
      begin
        lAusgabe.Caption  := 'Herzlichen Glückwunsch!!!';
        lBeginnen.Caption := 'Wählen sie einen Schwierigkeitsgrad';             //Mit Schwierigkeitsgrad kann man spiel neu starten
      end;
end;

procedure TForm1.ComputerverrtdieZahl1Click(Sender: TObject);                   //Fake Objekt
begin
  ShowMessage('Spiel Fair sonst hat es doch kein Sinn das ich mich hier Stunden lang hinsetzte und du dann schummeln willst.');
end;

procedure TForm1.ZumGewinnen1Click(Sender: TObject);                            //Fake Objekt
begin
  lVersuche.Caption := 'Sie haben keine Versuche mehr' +#10#13'da sie Schummeln' +#10#13'wollten. Klicken Sie Neustart' +#10#13'um von vorne zu beginnen.';
  Versuch := 0;
end;

procedure TForm1.Schlieen1Click(Sender: TObject);                               //schließt Programm
begin
  close;
end;

procedure TForm1.Neustarten1Click(Sender: TObject);
begin
  Randomize;
  edEingabe.Text   := '';                                                       //Soll alles zurücksetzten
  lAusgabe.Caption := '';
    if Optionen1 = oEasy then          //Problem     //Soll eigendlich den Einfach Modus wieder starten(wenn er gespielt wurde)
      begin
        Wurfel            := Random(101);
        Versuch           := 7;                                                 //Versuche auf 7 setzten und neu Würfeln
        lVersuche.Caption := 'Sie haben 7 Versuche';
      end;
    if Optionen1 = oMedium then       //Problem      //Soll eigendlich den Mittleren Modus wieder starten(wenn er gespielt wurde)
      begin
        Wurfel            := Random(101);
        Versuch           := 5;                                                 //versuche auf 5 setzten und neu Würfeln
        lVersuche.Caption := 'Sie haben 5 Versuche';
      end;
    if Optionen1 = oHard then         //Problem      //Soll eigendlich den Schweren Modus wieder starten(wenn er gespielt wurde)
      begin
        lAusdenken.Caption := 'Ich denke mir eine Zahl von 0 bis 200. Viel Spaß beim Raten';
        Wurfel             := Random(201);
        Versuch            := 7;                                                //Versuche auf 7 setzten und eine Zahl zwischen 0-200 Würfeln
        lVersuche.Caption  := 'Sie haben 7 Versuche';
      end;
end;
procedure TForm1.oEasyClick(Sender: TObject);                                   //einfachen Modus wählen
begin
  Randomize;
  Wurfel            := Random(101);
  Versuch           := 7;                                                       //Versuche auf 7 setzten und neu Würfeln Text zurücksetzten
  lVersuche.Caption := 'Sie haben 7 Versuche';
  edEingabe.Text    := '';
  lAusgabe.Caption  := '';
end;

procedure TForm1.oMediumClick(Sender: TObject);                                 //Mittleren Modus wählen
begin
  Randomize;
  Wurfel            := Random(101);
  Versuch           := 5;
  lVersuche.Caption := 'Sie haben 5 Versuche';                                  //Versuche auf 5 setzten und neu Würfeln Text zurücksetzten
  edEingabe.Text    := '';
  lAusgabe.Caption  := '';
end;

procedure TForm1.oHardClick(Sender: TObject);                                   //Schweren Modus starten
begin
  lAusdenken.Caption := 'Ich denke mir eine Zahl von 0 bis 200. Viel Spaß beim Raten';
  Randomize;
  Wurfel             := Random(201);              
  Versuch            := 7;
  lVersuche.Caption  := 'Sie haben 7 Versuche';                                 //Versuche auf 7 setzten und neu Würfeln Text zurücksetzten btw anpassen
  edEingabe.Text     := '';
  lAusgabe.Caption   := '';
end;


Xion - Mo 20.02.12 13:40

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
wollte aber noch das auf einem Label eine Zeit angezeigt wird wie lange das Spiel schon geht

Dazu kannst du eine Timer-Komponente nutzen. Beim Start des Spiels rufst du startTime:=GetTickCount auf. Im Timer erhälst du mittels GetTickCount-startTime die vergangene Zeit (in ms glaub ich). Dies kannst du dann einfach ausgeben.

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
Und wie kann ich einfügen, dass der Neustart das Neustartet welcher Schwierigkeitsgrad gewählt ist. Er Setzt dann nur die die Labels zurück aber die Versuche bleiben gleich.

Eigentlich gilt hier: eine Frage pro Thread. Da es dein Erster ist, will ich mal nicht so sein ;)

Du schreibst in Optionen1 nie etwas rein. Das solltest du (vermutlich) beim Einstellen des Schwierigkeitsgrads tun (oMediumClick usw). Zudem solltest du es irgendwann mal initialisieren beim Start des Programms.


Blubba - Mo 20.02.12 13:45

Ok das mit der Zeit werde ich gleich mal ausprobieren, hört sich nicht schwer an.
Edit: Soll das in FromCreate?

Und zu Punkt 2 weis ich gerade nicht was du genau meinst...


Xion - Mo 20.02.12 13:52

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
Ok das mit der Zeit werde ich gleich mal ausprobieren, hört sich nicht schwer an.
Edit: Soll das in FromCreate?

Dann wenn die Zeitmessung beginnen soll ;) Ich denke mal du willst messen, wie lange der Spieler für ein Spiel braucht (dann solltest du es beim Neustart machen).

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
Und zu Punkt 2 weis ich gerade nicht was du genau meinst...

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
    if Optionen1 = oEasy then          //Problem     //Soll eigendlich den Einfach Modus    
       [...]
    if Optionen1 = oMedium then       //Problem      //Soll eigendlich den Mittleren Modus wieder starten(wenn er gespielt wurde)
       [...]
    if Optionen1 = oHard then         //Problem      //Soll eigendlich den Schweren Modus wieder starten(wenn er gespielt wurde)
       [...]

Du prüfst hier die Variable Optionen1, aber die wurde (in dem gezeigten Code) nie gesetzt


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.oEasyClick(Sender: TObject);                                   //einfachen Modus wählen
begin
  Randomize;
  Wurfel            := Random(101);
  Versuch           := 7;                                                       //Versuche auf 7 setzten und neu Würfeln Text zurücksetzten
  lVersuche.Caption := 'Sie haben 7 Versuche';
  edEingabe.Text    := '';
  lAusgabe.Caption  := '';
  Optionen1 := oEasy;
end;

Das könnte helfen ;)


Blubba - Mo 20.02.12 13:58

Mh er startet Immer noch nicht die jeweilige If Stelle setzt nur die Labels zurück.
Optionen1 ist das dann eine Variable und wenn ja welchen Typ muss sie bekommen?


Xion - Mo 20.02.12 13:59

:nixweiss: Die Variable hast DU doch benutzt in deinem Code, du musst (solltest) doch wissen was sie bedeuted und welchen Typ sie hat.


Blubba - Mo 20.02.12 14:03

HiHi ja müsste ich aber eigendlich ist das der name von dem MainMenü und dem Reiter Optionen.
Und da dachte ich, dass wenn Optionen1 auf oEasy steht das eigendlich Starten würde...

Bin noch recht neu Was Delphi angeht.


Xion - Mo 20.02.12 14:08

Achso. Das geht so nicht. In dem Vergleich vergleichst du ein Menu mit einem Eintrag. Das ist wie Äpfel und Birnen, die sind nicht gleich ;)

Du solltest dir da eine eigene Variable anlegen, in der du das speicherst.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//vor der Definition type TForm1=class ganz oben
type TSpielmodus=(mEasy,mMedium,mHard);

//bei deinen Variablen
var Spielmodus: TSpielmodus; 

//beim Klick auf einen Menueintrag( oEasyClick )
Spielmodus:=mEasy;

//irgendwo im OnCreate
Spielmodus:=mMedium; //default ist mittlerer Schwierigkeitsgrad

//Spielmodus überprüfen
if Spielmodus=mEasy then
  [...]
else if Spielmodus=mMedium then
  [...]


Blubba - Mo 20.02.12 14:12

Birnen Und Äpfel kann man Vergleichen :P

Also es hat jetzte so geklappt das ich erst ein Modus auswählen muss und dann erfüllt der Neustart Button seine Funktion.

Kann man ein Popup erscheinen lassen bevor es startet? Das man erst den Schwierigkeitsgrad wählen muss?
Dann wäre das Problem schonmal gelöst.


Xion - Mo 20.02.12 14:16

Kann man machen (ShowMessage). Das ist aber nicht so gut, weil dann dein Programm fehlerhaft läuft, wenn man das Popup ignoriert. Du kannst auch (etwas unsauber) per Code "draufklicken":


Delphi-Quelltext
1:
oEasyClick(Self);                    

ins OnCreate


Blubba - Mo 20.02.12 14:23

Wieso läuft es dann Fehlerhaft?
Ich dachte da so an wie wenn man einen Editor schließt und dann kommt ja auch ien Fenster mit 'Sie haben nciht gespeichert wollen sie Speichern' und dann die 3 Auswahlmöglichkeiten.
Kann man das nciht einbauen?


Xion - Mo 20.02.12 14:41

Ah, ok, das kann man natürlich machen. Mir fällt auf Anhieb jetzt keine einfacher Lösung als das hier ein:
http://www.delphi-library.de/topic_ButtonBezeichnung+in+einem+MessageDlg+Fenster+aendern_22600,0.html

Einfacher wäre es wohl, eine eigene Form zu erstellen dafür.

Oder aber das Spiel kann überhaupt nicht beginnen, bis man im Menu eine Schwierigkeit gewählt hat.


Blubba - Mo 20.02.12 14:45

Einfach legt jeder auf eigene Weise aus ich versuche Mal durchzusteigen und hoffen zu verstehen.
Naja Übung macht den Meister wenn es auch lange dauert -.-

So hab nun Mal die Zeitausprobiert, GetTickCount ist doch der Befehl und startTime die Variable oder?


Xion - Mo 20.02.12 14:48

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
So hab nun Mal die Zeitausprobiert, GetTickCount ist doch der Befehl und startTime die Variable oder?


Ja ;)


Blubba - Mo 20.02.12 14:59


Delphi-Quelltext
1:
var startZeit : Integer;                    


Delphi-Quelltext
1:
lZeit.Caption := GetTickCount - startTime;                    


Delphi-Quelltext
1:
2:
3:
startTime := GetTickCount
  GetTickCount - startTime;
  lZeit.Caption :=  startTime;

Das bestimmt sau simpel aber irgendwie haupt es bei mir nicht hin-.-
Also beide Varianten hauen nicht hin


Xion - Mo 20.02.12 15:05


Delphi-Quelltext
1:
var startZeit : cardinal;                    


Delphi-Quelltext
1:
lZeit.Caption := IntToStr( GetTickCount - startTime )+'ms';                    


Delphi-Quelltext
1:
2:
startTime := GetTickCount;
lZeit.Caption := IntToStr( GetTickCount - startTime )+'ms';


Blubba - Mo 20.02.12 15:13

Ähm ja... 0ms
Das Programm will mich mobben-.-


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var startZeit : cardinal;

procedure TForm1.Neustarten1Click(Sender: TObject);
begin
  Randomize;
  edEingabe.Text   := '';                                                      
  lAusgabe.Caption := '';
  startTime := GetTickCount;
  lZeit.Caption := IntToStr( GetTickCount - startTime )+'ms';
    if Optionen1 = oEasy then

Steht die ganze Zeit auf 0


Xion - Mo 20.02.12 15:16

Du musst das Caption des Labels noch in einem Timer setzen (also immer wieder). Also eine TTimer-Komponente nutzen und im OnTimer das Caption setzen. Fertig :)

Falls es dann flackert, setze Form1.DoubleBuffered:=true;

Edit: Du solltest den Timer erst aktivieren (Enabled:=true) beim Neustart.


Blubba - Mo 20.02.12 15:30

Ist das Jetzte Normal das er Den Text immer wieder Löscht der ins Editfeld kommt und den Hinweis? Und jetzte geht das mit Versuchen zurück setzten nichtmehr-.-


Xion - Mo 20.02.12 15:34

Es sollte etwa so aussehen:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.TimerOnTimer(Sender: TObject);
begin
   lZeit.Caption := IntToStr( GetTickCount - startTime )+'ms';
end;


klingt ganz so aus würdest du hier zu viel machen lassen.


Blubba - Mo 20.02.12 15:40

Ah Endlich Vielen Dank :idea:
Ich schätze mal nciht das Es jetzte noch ne Variante gibt damit ein Ottonormalverbraucher weiß wie viele Sec es sind?

Und eine Stop Funktion wenn man gewonnen hat btw Verloren.

P.s. Ich hoffe ich bin net zu nevig :wink:


Xion - Mo 20.02.12 16:08

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:

Ich schätze mal nciht das Es jetzte noch ne Variante gibt damit ein Ottonormalverbraucher weiß wie viele Sec es sind?

In Sekunden umrechnen ist nicht das Problem ;) Einfach den Wert durch 1000 Teilen (und dann statt InttoStr FloatToStr verwenden.

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
Und eine Stop Funktion wenn man gewonnen hat btw Verloren.

Timer.Enabled:=False :mrgreen:

user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:
P.s. Ich hoffe ich bin net zu nevig :wink:

Achwas, dann würde ich einfach nicht mehr antworten ;)


Blubba - Mo 20.02.12 16:20

LoL
_______________________
Danke
Programmieren ist viel zu kompliziert können die da net einfach klare Ansagen Machen xD

Moderiert von user profile iconNarses: Beiträge zusammengefasst

Ups ich nochmal...

Delphi-Quelltext
1:
lZeit.Caption := IntToStr( GetTickCount - startTime / 1000 )+'ms';                    

oder

Delphi-Quelltext
1:
lZeit.Caption := IntToStr( StrToInt('GetTickCount - startTime / 1000') )+'ms';                    

Hatte ich jetzte doch er gibt mir beim 2. Aus kein Korrekter Integer und beim ersten Compilieren-.- :?

Edit:
und dann hatte ich noch diese Lösung
Ich setzte das Laber auf 0
und dann

Delphi-Quelltext
1:
//lZeit.caption:=inttostr(strtoint(lZeit.caption)+1);                    

Das ging zwar aber als ich +'sec' dahinter setzten wollte brach er ab.


Xion - Mo 20.02.12 17:31

Am besten du guckst da mal rein:
http://www.christian-stelzmann.de/index_tutorials_crashkurs.html

Variablen haben Typen wie String (Zeichenkette), Integer (Ganzzahl), Real (Kommazahl)

Mit IntToStr wandelst du um (also Integer nach String, z.B. 5 -> '5').
Mit StrToInt wandelst du um (also String nach Integer, z.B. '5' -> 5 ).

Was du jetzt machen willst ist

String -> Integer
'1sec' -> ???
Was soll 1sec für eine Zahl sein?

Das selbe, du machst IntToStr, aber gibst ihm eine Kommazahl und keinen Integer. Dafür musst du FloatToStr nutzen (da Float = FloatingPoint).

IntToStr(4.5) geht nicht
FloatToStr(4.5) = '4,5'

Sei froh dass das so ist, in C++ ist das nämlich nicht so. Der konvertiert da alles durcheinander. '1sec' als integer wäre da dann irgend eine Speicheradresse, wo '1sec' grad drinsteht. Und er führt Rundungen durch, ohne etwas zu sagen. In Delphi geht das so:

IntToStr(Round(4.2)) = '4'

Und Caption ist eben vom Typ Zeichenkette, deine Zeit vom Typ Ganzzahl, und Zeit/1000 vom Typ Gleitkomma.

Edit:
Klammern nicht vergessen, sonst kommt Quatsch raus:
user profile iconBlubba hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
lZeit.Caption := IntToStr( ( GetTickCount - startTime ) / 1000 )+'ms';                    


Blubba - Di 21.02.12 10:05

Ah Danke nochmal =)