Entwickler-Ecke
Sonstiges (Delphi) - Quiz programmieren
01Detlef - Mo 09.12.02 19:19
Titel: Quiz programmieren
hallo,
ich bin dabei, ein kleines quiz zu proggen und nun möchte ich, dass man zwei versuche hat, wie kann ich das machen?
mein programm ist mit 4Labels, einem Button und einem editfeld ausgestattet! in das editfeld kann man a-d eingeben und wenn edit1.text gleich z.B a ist und das richtig ist, kommt die nächste frage!
Jetzt soll man halt zwei versuche haben und erst beim 3 von neu anfangen!
Mein Vorschlag:(wahrscheinlich vollkommen falsch*G*)
Quelltext
1: 2: 3: 4: 5: 6: 7:
| Versuche:=2 REPEAT form1.show UNTIL versuche:=2; IF versuche>2 then form1.close; IF versuche<=2 then showmessage('toll'); |
Das Problem ist jetzt nur, wie mache ich das, dass er "Versuche" gebraucht, um form1 nochmal anzuziegen? Was ist alles falsch an meiner Idee?
Christian S. - Mo 09.12.02 22:37
Ich muss Dir leider bestätigen, dass Dein Ansatz vollkommen falsch ist.
| Zitat: |
Quelltext 1: 2:
| REPEAT form1.show UNTIL versuche:=2; | |
Hier stecken schon zwei Fehler drin:
1. Da wird gar keine Benutzereingabe erwartet.
2. (Ich gehe davon aus, dass es "=" und nicht ":=" heissen sollte.) Die Variable "Versuche" wird überhaupt nicht geändert, eine Überprüfung ist sinnlos. Da Du "Versuche" vorher auf 2 setzt, wird sie jedesmal genau einmal ausgeführt.
Nun zu den IF-Abfragen.
Allgemein:
Da Du "Versuche" gar nicht änderst ist es nicht sinnvoll eine Abfrage zu machen.
speziell zu 2: Es ist vielleicht nicht wirklich gut, das Programm zu beenden, wenn jemand zwei falsche Antworten gegeben hat.
So, nun eine kleine Anleitung, wie Du es richtig machen kannst:
1. Sobald eine neue Frage angezeigt wird, setzt Du in einem Rutsch direkt auch mal die Variable Versuche auf 0. Denn der Benutzer hat ja noch keine Antwort auf diese (neue) Frage gegeben, hatte also Null Versuche. Die Variable sollte global deklariert sein, damit alle Prozeduren / Funktionen Zugriff darauf haben.
2. Du möchtest, jedes mal wenn der Benutzer einen Eingabe getätigt hat, abfragen, ob diese richtig ist oder nicht, und entsprechende Aktionen ausführen. Geben wir dem Benutzer die Chance, seine Eingabe so oft zu ändern wie er will, bis er sie abschickt und stellen ihm eine Button "OK" zu verfügung, den er drücken soll, wenn er meint die Antwort wäre richtig.
3. Wenn er also "OK" drückt (OnClick), überprüfst du den Inhalt von edit1. Dieser ist entweder falsch oder richtig.
Ist er richtig, wird die neue Frage angezeigt, "Versuche" wieder (in einem Rutsch) auf Null gesetzt usw.
Ist die Antwort falsch, wird "Versuche" um eins erhöht und eine Meldung ausgegeben.
Dann musst Du noch prüfen, ob das vielleicht schon sein zweiter Versuch war, dann müsste "Versuche" nun den Wert 2 beinhalten. War das schon sein zweiter Versuch, kannst Du das Spiel beenden (fände ich nicht so toll), ihm Punkte abziehen oder was Du auch immer für richtig hälst.
So, dass sollte als Anleitung erst einmal genügen. Hoffe ich.
MfG,
Peter
Wolff68 - Mo 09.12.02 22:46
Ich wusste ja, daß der Monitor das Bild immer wieder neu aufgebauen muß, aber ein Formular? :wink:
Mit Form1.Show zeigst Du das Formular an. Und das bleibt solange da bis Du es zumachst. (Mit Form.Close zB)
Alles was Du in Delphi machen musst, ist auf Aktionen reagieren.
Der Benutzer schreibt seine Lösung in das Edit und klickt der Einfachheit halber danach auf Button1.
Dann prüfst Du im Onclick-Ereignis des Buttons, ob das richtig war oder nicht. Soweit so gut.
Jetzt solltest Du Dir noch irgendwo merken wie oft er daneben gelegen hat. Also oben eine Globale Variable definieren und diese möglichst noch vor der ersten Frage auf 2 setzen.
Wenn die Frage richtig war gehst Du die nächste Frage anzeigen und setzt den Zähler wieder auf 2.
War sie falsch ziehst Du von der 2 eins ab und prüfst danach ob sie jetzt 0 ist. Wenn sie 0 ist, dann 'Game Over', sonst weiter. Von mir aus kannst bei 'Game Over' dann auch Dein Programm beenden, wobei es netter wäre den Benutzer zumindest mit einem ShowMessage('GAME OVER'); darauf hinzuweisen.
Probier mal ob Du das hinbekommst.
Christian S. - Mo 09.12.02 22:49
Okay, okay, ich gebe zu: meine Antwort war ein bisschen zu ausführlich ...
Wolff68 - Mo 09.12.02 22:50
Aber vielleicht besser zu verstehen als meine,...
:beer:
Christian S. - Mo 09.12.02 22:51
:beer:
01Detlef - Di 10.12.02 16:13
Vielen Dank, aber ich komme nicht weiter, wenn ich versuche+1 habe, ich muss doch irgendwie eine Schleife aufbauen oder?
Quelltext
1: 2: 3: 4: 5: 6: 7:
| Versuche:=0; IF edit1.text='a' THEN form2.show ELSE showmessage('falsch, noch ein Versuch'); versuche:=versuche+1; END; |
Ich muss das ganze doch nochmal durchlaufen lassen, wenn edit1.text nicht a ist!! Solange bis versuche gleich 2 ist und dann soll alles von vorne anfangen! Vielleicht mit einer For-Schleife, so dass Versuche+1 bespeichert wird und nochmal der Versuch gestartet wird? Oder geht das auch anders? (repeat-schleife, weil edit1.text doch die Eingabe ist und dieses wiederholen bis versuche gleich 2 ist oder so??)
Danke Detlef
Danke Detlef
Christian S. - Di 10.12.02 16:27
Im Grunde genommen hast Du ja eine versteckte Schleife: das OnClick-Ereignis des Buttons, den der Benutzer drückt, wenn er seine Antwort abgibt. Denn das, was in diesem Ereignis an Code drin steht, wird ja mehrmals ausgeführt (jedesmal, wenn der Button gedrückt wird).
Bis auf das "versuche:=0" kommt der von die gepostete Code in das OnClick-Ereignis. Am Ende musst Du allerdings dann noch prüfen, ob versuche=2 ist, damit Du das Spiel beenden kannst, wenn zwei falsche Antworten gegeben worden sind.
Das "versuche:=0" solltest Du immer nur dann aufrufen, wenn eine neue Frage gezeigt wird.
MfG,
Peter
a.C.k - Di 10.12.02 16:44
Wenn ich dein Problem richtig verstehe, dann brauchst du keine Schleife.
Du möchtest doch abwarte, was der Benutzer antwortet, oder?
Also, einen Wert eingibt.
Dann reagierst du auf den Wert...
Wenn du eine Schleife nimmst, und erhöhst bei jeder falschen antwort versuche um 1, dann hat der Benutzer ja gar keine Zeit zu antworten.
#Delphi ist (wie schon gesagt wurde) eine ereignisorientierte Sprache.
Die Ereignisse einer Komponente findest du im Objektinspektor neben den Eigenschafften auf der rechten seite.
Also wenn der Benutzer eine Antwort schreibt, reicht es z.B. bei einem Buton Click einmal nachzuschauen, ob es die Richtige Antort war...
Also:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| IF Antwort = richtig THEN begin Versuche := 0; nächste Frage; end ELSE begin IF Versuche <3 THEN begin showmesage('leider Falsch....') Versuche := Versuche +1 ; //bzw. INC(Versuche) end ELSE begin showmessage('Game Over.....'); Close; end; end; |
Du fragst ja immer nur ab, ob er dieses eine mal die richtige Antwort gegeben hat, nicht permanent. Deshalb benötigst du uch keine Schleife.
diese ganze Prozedure wird ja jedesmal durchlaufen, wenn du den Button drückst.
01Detlef - Di 10.12.02 19:20
Also vielen Dank, ich hatte den fehler gemacht, dass der Button eine Schleife ist!
Aber der Quelltext von a.C.K ermöglicht mir nur eine Antwort, das gleiche Problem hatte ich auch! Nach dem ersten Versuch zeigt er showmessage('Game Over') und das Programm beginnt von vorne!!!
Wieso????
Danke Detlef
Christian S. - Di 10.12.02 19:25
In a.C.k.'s Quelltext kann ich da nichts erkennen. Poste doch mal Deinen Quelltext. Der vom Button sollte reichen.
01Detlef - Di 10.12.02 20:16
Ich meine ja, a.c.k's Quelltext, wenn ich das compiliere, habe ich nur einen Versuch, nicht zwei! Wieso ist das so, der soll doch solange wiederholen, wie <3 gilt????
Meinen Quelltext, brauch ich nicht texten, weil das gleiche Problem ist und ein wenig unstrukturierter aufgebaut ist!!
Danke Detlef
Christian S. - Di 10.12.02 20:21
Der hier gepostete Quelltext kann ja aber nicht der komplette sein. Folgende Fragen:
1. Wie initialisierst Du "versuche" (bevor der Nutzer das erste Mal auf den Button gedrückt hat)?
2. Wie ermittelst Du, was "antwort" für einen Wert hat?
3. fällt mir nicht ein
MfG,
Peter
01Detlef - Di 10.12.02 20:26
also
1) versuche hab ich als Integer deklariert und sonst so wie in dem Code!
2)für Antwort habe ich edit1.text eingesetzt!
Detlef
Christian S. - Di 10.12.02 20:46
So sieht's bei mir aus und es funktioniert:
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:
| var Form1: TForm1; versuche: Integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin versuche:=0; end;
procedure TForm1.Button1Click(Sender: TObject); VAR antwort : STRING; begin Antwort:=edit1.text; IF Antwort = 'a' THEN begin Versuche := 0; ShowMessage('Jetzt käme die nächste Frage'); end ELSE begin IF Versuche <3 THEN begin showmessage('leider Falsch....'); Versuche := Versuche +1 ; //bzw. INC(Versuche) end ELSE begin showmessage('Game Over.....'); Close; end; end; end; |
MfG,
Peter
01Detlef - Mi 11.12.02 16:27
also, meine Fragen:
1)sagen wir mal, ich möchte nur eine Frage machen (*blödsinn,aber mal angenommen*);
dann kann ich doch auch
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TForm1.Button1Click(Sender: TObject);
VAR antwort : STRING; versuche:INTEGER; begin Antwort:=edit1.text; IF Antwort = 'a' THEN begin Versuche := 0; ShowMessage('Jetzt käme die nächste Frage'); end ELSE begin IF Versuche <3 THEN begin showmessage('leider Falsch....'); Versuche := Versuche +1 ; //bzw. INC(Versuche) end ELSE begin showmessage('Game Over.....'); Close; end; end; end; |
wieso muss Antort:=edit1.text vorher zugewiesen werden, warum nicht
if edit1.text='' then..
Quelltext
1: 2: 3: 4:
| procedure TForm1.FormCreate(Sender: TObject); begin versuche:=0; end; |
kann ich das weglassen, wenn nur eine Frage sein soll?
Das sagt doch, dass nach formcreate versuche immer 0 ist oder?
Danke Detlef
a.C.k - Mi 11.12.02 16:38
Weglassen würde ich es nicht, da es ansonsten sein kann, dass Versuch irgendwelche Zufallswerte bekommt.
Muss nicht zwingend im Form.Create Ereignis stehen. Kannst genau so gut woanders uf Null setzten. (z.B. Neues Spiel, oder so..)
zu frage 1.
Die Variable "Antwort" kannst du dir Sparen. Macht das ganze aber übersichtlicher. Natürlich kannst du auch Antwort durch Edit1.text ersetzen...
01Detlef - Mi 11.12.02 16:44
also, ich habe deinen quelltext genauso abgeschrieben (nur das form.dreate da nicht) und nun habe ich unendlich viele Versuche!!
Kann das sein, wenn ich einmal falsch klicke versuche+1 im speicher nicht gespeichert wird und nun immer wieder von versuche:=0 begonnen wird? Dadurch habe ich ja unendlich viele versuche!!
Aber wieso hat es bei dir geklappt? Ich möchte zwei Versuche!!
Danke Detlef
a.C.k - Mi 11.12.02 17:05
Habe das nicht Programmiert sondern nur so aufgeschrieben.
She jetzt den Fehler (glaube ich zumindest...).
Nehme mal versuche aus der Deklaration der Prozdeure raus und mach ne Globale Variable daraus.
dann sollte es klappen.
Form.Create solltest du aber auch noch einbauen.
01Detlef - Do 12.12.02 17:12
Also ihr dürft mich nicht fragen wieso, aber nun habe ich ein wenig ausprobiert und getestet und es läuft!!!!!*G* Total seltsam aber es läuft
guck euch das an:
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:
| var Form1: TForm1; Versuche:Integer; implementation
uses Frage2;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin Versuche:=0; end;
procedure TForm1.Button1Click(Sender: TObject); var antwort: STRING; begin Antwort:=edit1.text; IF Antwort = 'a' THEN begin Versuche := 0; Form2.show; end ELSE begin IF Versuche <1 THEN begin showmessage('leider Falsch....'); Versuche := Versuche +1 ; //bzw. INC(Versuche) end ELSE
IF Versuche >= 1 THEN BEGIN showmessage('Game Over.....'); form1.close; end; end; end;
end. |
Jetzt habe ich zwei versuche!! aber warum versuche >= 1?? Nur so läuft es, dass ich 2 versuche habe!1 Komisch! kann mir das noch einer erklären, dann ist das Thema abgegehakt!!
Danke Detlef
Christian S. - Do 12.12.02 17:25
Wenn Du die Zeile rausschmeisst, läuft das Programm bestimmt immer noch. Das kann keinen Unterschied machen.
a.C.k - Do 12.12.02 17:39
Du hast bestimmt das "TForm1.FormCreate" so eingefügt...
Mach das mal in deinem Hauptformular (sollte Form1 sein..) über den Objektinspektor. Ereignisse -> OnGreate...
01Detlef - Do 12.12.02 17:55
Meiine FRage ist jetzt nur, was die 1 da überhaupt soll, ich wollte doch 2 versuche...
und jetzt noch eine andere sache, ich habe 3 forms und nun möchte ich die reihenfolge ändern, in der sie in der .exe aufgerufen werden, wie geht das?? also jetzt ist in der reihenfolge 3-2-1 programmiert, mit den links und so und nun will ich 1-2-3, wie ändere ich das??
Danke Detlef
Christian S. - Do 12.12.02 18:05
1. Wo hast Du die 1 denn überhaupt her. Da sollte beide Male eine 2 stehen. Und es muss auch mit der 2 funktionieren.
2. Du kannst in den Optionen zum aktuellen Projekt einstelle, in welcher Reihenfolge die Formen erstellt werden sollen. Dann änderst Du noch die Links. Ich würde ja nicht für jede Frage eine neue Form aufrufen. Speichere doch Frage und Antwort in einem Array und ändere bei einer neuen Frage einfach nur das Label, in dem die Frage steht.
01Detlef - Mo 23.12.02 21:40
danke,
sorrey das ich jetzt erst schreibe.
zu 2) ich habe jetzt auch gemerkt, dass ich nicht immer ein form öffnen sollte, viele fehler und speicherplatz!
Nur mit dem array ist das ziemlich schwer, ich muss die fragen darin speichern, die antworten und die korrekten Antworten! Muss ich da einen vierdimensionalen Array aufbauen oder muss ich da was mit type aufbauen?
Kann mir da einer helfen?
Danke Detlef
Christian S. - Do 26.12.02 20:56
Warum möchtest Du die korrekten Antworten speichern?
Aber sowohl die Idee mit den mehreren Dimensionen als auch das mit dem Type sind gut. In diesem Fall ist es ziemlich egal, welche der beiden Arten du nimmst, aber um den Lerneffekt hoch zu halten, versuche ich jetz mal zu erklären, wie das mit dem Type geht.
Ich würde hier einen Record verwenden. Also so:
Quelltext
1: 2: 3: 4:
| TYPE TFrage = RECORD Frage : STRING[200]; Antwort: Char; END; |
Diese schreibst Du dann in ein Array. So:
Quelltext
1:
| VAR Frage : ARRAY OF TFrage; |
oder, wenn die Anzahl der Fragen bekannt und z.B. 20 ist:
Quelltext
1:
| VAR Frage : ARRAY[0..19] OF TFrage; |
Außerdem solltest Du global speichern, bei welcher Frage du gerade bist.
So, und dann gehst Du ganz einfach alle Fragen durch.
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:
| procedure TForm1.FormCreate(Sender: TObject); begin Versuche:=0; //... //hier musst Du jetzt noch Dein Array füllen. Ich würde mir ein kleines //Programm schreiben, in das Du Frage und Antwort eingeben kannst, //und welches alles in eine Datei speichert, die dann hier gelesen wird. //... nummer:=0; Label_Frage.Caption:=Frage[nummer].Frage; end;
procedure TForm1.Button1Click(Sender: TObject); var antwort: STRING; begin Antwort:=edit1.text[1]; IF Antwort = Frage[nummer].Antwort THEN begin Versuche := 0; inc(nummer); Label_Frage.Caption:=Frage[nummer].Frage; end ELSE begin IF Versuche <1 THEN begin showmessage('leider Falsch....'); Versuche := Versuche +1 ; //bzw. INC(Versuche) end ELSE
IF Versuche >= 1 THEN BEGIN showmessage('Game Over.....'); form1.close; end; end; end; |
So (oder so ähnlich) müsste es gehen. Da mir das Programm drum herum fehlt, konnte ich den Quelltext nicht testen. Ein paar Fehler können sich da also eingeschlichen haben.
MfG,
Peter
01Detlef - Mo 06.01.03 20:01
frohes neues jahr,
da ich im urlaub war kann ich erst jetzt antworten.
also die prozedur mit den versuchen habe ich modifizert, aber mein problem besteht darin, die fragen bzw. antworten also die arrays in das programm einzufügen!
am besten wäre ja eine eigene datei, die die zuweisungen beinhaltet, aber wie mache ich das mit den arrays?
Danke Detlef
Christian S. - Mo 06.01.03 20:19
Hi!
Wie Du Arrays in einer Datei speicherst und liest, hatte ich in
hier [
http://www.auq.de/viewtopic.php?t=5507] mal erklärt. Wie gesagt: du solltest Dir ein Miniprogramm schreiben, mit dem Du ganz einfach Fragen und Antworten in einer Datei speichern kannst, die von deinem Quizprogramm dann gelesen wird.
Entschuldige, dass ich nicht ausführlicher antworte, aber im Moment habe ich noch einiges zu tun. Aber vielleicht hilft Dir das hier schon mal weiter.
MfG,
Peter
01Detlef - Di 07.01.03 15:17
danke,
ich denke doch richtig, dass ich in diese datei das type mit den array speichern muss? datein einzulesen muss ich mich erst informieren.
und um die infos den labels zuzuweisen benutze ich die array und die for schleife?
wie weise ich denn den labels einen text zu?
label1.caption:='sdfs';??
Danke Detlef
Christian S. - Di 07.01.03 16:31
Hi!
So, jetzt habe ich wieder mehr Zeit und kann die Defizite meiner vorigen Antwort ein bisschen aufholen. :wink:
Nehmen wir mal an, Deine Fragen und Antworten sind in der Datei "jauch.dat" gespeichert, die im Root-Verzeichnis liegt. Wie die Fragen und Antworten dort hinein kommen, dazu später.
Folgender Code im OnCreate-Ereignis Deiner Hauptform läft die Fragen und Antworten in Dein Array 'frage : ARRAY OF TFrage':
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| VAR my_file : File of TFrage; begin SetLength(Frage,0); //Array 'Frage' soll am Anfang 0 Datensätze enthalten AssignFile(my_file,'jauch.dat'); //Weise der Datei den Dateinamen zu {$I-} //Fehlermeldung "ausschalten" Reset(my_file); //Datei öffnen {$I+} //Fehlermeldung "einschalten" IF IOResult=0 then begin //Wurde die Aktion korrekt ausgeführt? while not eof(my_file) do //Solange das Ende der Datei nicht erreicht wurde... begin SetLength(frage,Length(frage)+1); //Ergänze das Array "Frage" um einen Datensatz Read(my_file,frage[High(frage)]); //Lese den gerade erzeugten Datensatz aus der Datei end; CloseFile(my_file); //Datei wieder schließen end; end; |
Wenn Du eine solche Datei erstellen willst (also die Datensätze eines bestehenden Arrays speichern willst), dann machst Du das so:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| VAR my_file : File of TFrage; begin AssignFile(my_file,'jauch.dat'); //Weise der Datei den Dateinamen zu {$I-} //Fehlermeldung "ausschalten" ReWrite(my_file); //Datei neu schreiben, ACHTUNG: bestehende Datei wird überschrieben!!! {$I+} //Fehlermeldung "einschalten" IF IOResult=0 then begin //Wurde die Aktion korrekt ausgeführt? for i:=0 TO High(frage) DO //Vom ersten bis zum letzten Datensatz des Arrays 'Frage' ... Write(my_file,frage[i]); //...schreibe den Datensatz in die Datei CloseFile(my_file); //Datei wieder schließen end; end; |
Wie Du den Labels dann die Fragen zuweist, steht in meinem Posting vom 26.12.02 19:56h im dort als Code angebeben Button1Click-Ereignis.
Ich hoffe, ich konnte Dir dieses Mal besser helfen!
MfG,
Peter
01Detlef - Di 07.01.03 18:05
wirklich vielen dank!
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| VAR my_file : File of TFrage; begin AssignFile(my_file,'jauch.dat'); //Weise der Datei den Dateinamen zu {$I-} //Fehlermeldung "ausschalten" ReWrite(my_file); //Datei neu schreiben, ACHTUNG: bestehende Datei wird überschrieben!!! {$I+} //Fehlermeldung "einschalten" IF IOResult=0 then begin //Wurde die Aktion korrekt ausgeführt? for i:=0 TO High(frage) DO //Vom ersten bis zum letzten Datensatz des Arrays 'Frage' ... Write(my_file,frage[i]); //...schreibe den Datensatz in die Datei CloseFile(my_file); //Datei wieder schließen end; end; |
hier kommt jetzt mein array hinein?!?!?!? und mit dem anderen wird das gelesen, alles klar! (verstehen tue ich das noch nicht, aber das werde ich noch versuchen!)
also ich habe mir jetzt überlegt so den array zu füllen:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var Nummer: Integer;
Type TFrage = Record Frage : String; Antwort : char; var Frage : Array[1..15] of TFrage; For Frage:=1 to 15 do begin Frage[1].Frage:=.. and Frage[1].Antwort:= .. and nummer = 1 ;// kann man jetzt Frage[1].Frage:=Label1.. schreiben?............ |
reiß mir bitte nicht den kopf ab , auch wenn es komplett falsch ist, bitte!
ich weiss nämlich nicht, wie ich die drei sachen sonst in jede frage einbauen soll
(frage,antwort,nummer)
danke Detlef
Christian S. - Di 07.01.03 18:49
Hi!
| Zitat: |
| reiß mir bitte nicht den kopf ab , auch wenn es komplett falsch ist, bitte! |
Nein, bestimmt nicht. Nur durch ausprobieren lernt man. :D
| Zitat: |
| hier kommt jetzt mein array hinein?!?!?!? |
Damit wird Dein Array in eine Datei gespeichert, damit Du es wiederverwenden kannst.
| Zitat: |
| verstehen tue ich das noch nicht, aber das werde ich noch versuchen! |
Immer nachfragen, egal wie oft!
Nun zu Deinem Vorschlag: Sei
Du mir nicht böse, aber könntest Du erklären, was Du genau jetzt machen willst? Und auch ein paar Erklärungen zum Quelltext geben? (Ein paar Fehler sind mir schon aufgefallen, aber es ist wahrscheinlich sinnvoller, da erst etwas zu zu sagen, wenn ich genau weiß, was Du machen wolltest.)
MfG,
Peter
01Detlef - Mi 08.01.03 16:36
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var Nummer: Integer;
Type TFrage = Record Frage : String; Antwort : char; var Frage : Array[1..15] of TFrage;
For Frage:=1 to 15 do begin Frage[1].Frage:=.. and Frage[1].Antwort:= .. and nummer = 1 ;// kann man jetzt Frage[1].Frage:=Label1.. schreiben?............ |
ich muss doch für 15 fragen, jedem label (5 labels: 1=frage und 4=mögliche Antworten) eine zuweisung machen!
Deshalb habe ich jetzt das array genommen bzw. type um die zuweisungen zu machen.
Quelltext
1: 2:
| Frage[1].Frage:= // muss den labels die erste Frage/Antwort zugewiesen werden! Frage[1].Antwort:=// muss der richtige buchstabe hinein! |
kann das sein, dass du dafür einen array benutzt hast für die nummer?
Quelltext
1:
| IF Antwort = Frage[nummer].Antwort THEN |
dann verstehe ich aber nicht, wie du deinen array aufgebaut hast?
Frage[nummer]? muss in die klammer nicht immer die zahl also hier 1..15?
Danke erstmal Delef
Christian S. - Mi 08.01.03 17:25
| Zitat: |
| ich muss doch für 15 fragen, jedem label (5 labels: 1=frage und 4=mögliche Antworten) eine zuweisung machen! |
Ja, aber mit Deinem Code machst Du den gleichen Fehler, wie Du ihn ganz am Anfang gemacht hast: du brauchst diese Schleife nicht.
Das OnClick-Ereignis Deines Buttons ist für Dich die Schleife. Jedesmal, wenn eine Frage richtig beantwortet wurde, lädst Du einen neuen Text in deine Labels. Aber Du musst eigentlich nur Dein Label für die Frage ändern, da Du doch immer die gleichen Antwortmöglichkeiten hast ('a' bis 'd'). {Ich war davon ausgegangen, dass eine Frage beispielswiese so aussieht: "Was ist die Hauptstadt von Deutschland? (a: Düsseldorf, b:Bonn, c:Berlin, d:München)".} Und wie Du das machst, habe ich in meinem Posting vom 26.12. 19:56h bereits beschrieben. (Ich nehme an, daraus hast Du auch die von Dir zitierte IF-Abfrage.)
Nun zu Deiner Frage mit dem Array:
| Peter Lustig hat folgendes geschrieben: |
| Folgender Code im OnCreate-Ereignis Deiner Hauptform läft die Fragen und Antworten in Dein Array 'frage : ARRAY OF TFrage': |
Hiermit sollte doch eigentlich schon klar sein, dass ich die Fragen (mit ihren Antworten) in ein Array lade. Das Array hat so viele Elemente, wie es Fragen gibt. Jede Frage ist ein Element.
Mit der Variable'nummer' zähle ich, welche Frage gerade gefragt wird bzw. gefragt werden soll. Wenn ich also Frage 3 stellen möchte, muss ich das dritte Element des Arrays ansprechen. In meinem Beispiel beginne ich die Fragen allerdings ab 0 zu zählen, die Frage 3 hätte also 'nummer' = 2.
Nun, und was das ansprechen von Elementen eines Arrays anbelangt: das kann ich auch mit Variablen machen. Frage[nummer] ist also beispielsweise für nummer=0 das gleiche wie Frage[0], wenn nummer=5 ist, dann ist Frage[nummer] das gleiche wie Frage[5].
Ein Beispiel für Dein Array:
Quelltext
1: 2: 3: 4: 5:
| nummer Frage Antwort ---------------------------------------------------------- 0 Was ist ein Array? a 1 Was ist ein String? b 2 Was ist ein Integer? c |
In die Fragen würde jetzt noch die Aufzählung der Möglichkeiten gehören, aber dass ist ja nicht so wichtig jetzt. Wenn ich jetzt also eine Information aus dem Array abfragen möchte, muss ich zuerst angeben, welches Element (welche Zeile) des Arrays ich ansprechen möchte, und dann welche Eigenschaft des Record ich abfragen möchte. Nehmen wir an, ich möchte von 2. Element die Antwort wissen. Dann sieht das so aus:
Frage[1].Antwort
Ich hoffe, das klärt schon einiges (wenn wahrscheinlich auch nicht alles).
MfG,
Peter
01Detlef - Fr 10.01.03 19:33
hallo,
Aber ich muss doch nicht nur das label von der Frage ändern, die 4 Möglichkeiten sind doch von Frage zu Frage auch verschieden, nur a bis d bleibt gleich! a bis d wollte ich ja in eine edit-Kompo schreiben, wo das dann kontrolliert wird!
Also deinen Vorschlag habe ich verstanden, auch das der Buttonklick die schleife ist! Aber die ganze Umsetzung:
Die Daten müssen in einem Array gespeichert werden, Fragen und Antworten.
Die Nummer der Frage muss mit dem klick(wenn es richtig ist) um eins erhöht werden!
Nur diese ganzen Infos muss ich ja nun zusammenfassen! Wie mache ich das, mit dem array aufruf ohne eine for-schleife?
ich weiss, dass man die einzelnen nummern ansprechen kann mit [...]?!
Eine Sache habe ich noch gar nicht verstanden, wie füge ich meine eigenen Fragen dem Quiz zu (besser den Labels)??
Danke Detlef
Christian S. - Fr 10.01.03 19:55
Na dann mal los....
1. Das mit den Antworten war von mir falsch gedacht. So, wie Du es jetzt beschreibst, musst Du den Aufbau Deines Records noch umgestalten. Es sollte statt:
Quelltext
1: 2: 3: 4:
| TYPE TFrage = RECORD Frage : String; antwort : Char; END; |
jetzt so aussehen:
Quelltext
1: 2: 3: 4: 5:
| TYPE TFrage = RECORD Frage : String; a,b,c,d : String; antwort : Char; END; |
In 'Frage' ist weiterhin die Frage gespeichert, die 'a' bis 'd' enthalten die möglichen Antworten, 'antwort' entält weiterhin den Buchstaben, der der richtigen Antwort zugeordnet ist.
Damit muss sich dann auch Dein ButtonClick ändern, da Du da drin ja auch mehr Informationen verbraten musst.
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:
| procedure TForm1.Button1Click(Sender: TObject); var antwort: STRING; begin Antwort:=edit1.text[1]; IF Antwort = Frage[nummer].Antwort THEN begin Versuche := 0; inc(nummer); Label_Frage.Caption:=Frage[nummer].Frage; with Frage[nummer] do //ERKLRÄRUNG IM POSTING begin Label_a.Caption:=a; Label_b.Caption:=b; Label_c.Caption:=c; Label_d.Caption:=d; end; end ELSE begin IF Versuche <1 THEN begin showmessage('leider Falsch....'); Versuche := Versuche +1 ; //bzw. INC(Versuche) end ELSE
IF Versuche >= 1 THEN BEGIN showmessage('Game Over.....'); form1.close; end; end; end; |
So, wie Du siehst werden nun mehr Labels aktualisiert und auch auf eine ein bisschen andere Weise als vorher.
Ich habe den Code dahingehend vereinfacht, dass ich die WITH..DO-Funktion verwendet habe, die bei Objekten/Records einiges an Schreibarbeit spart. Diese Funktion sagt dem Compiler einfach, dass er Variablen, die nicht anderweitig definiert sind, in dem Record/Objekt suchen soll, welches in der WITH..DO-Zeile steht. In unserem Fall: die Variablen a,b,c,d stehen in keiner VAR-Zeile, sind also auch nicht definiert. Also sucht der Compiler sie in dem Record 'Frage[nummer]' und wird dort auch fündig.
| Zitat: |
| Wie mache ich das, mit dem array aufruf ohne eine for-schleife? |
Über die Variable nummer. Sie wird immer dann erhöht, wenn eine neue Frage geladen werden soll und damit auch der Index, der beim Array angesprochen wird, da ja Frage[nummer] angesprochen wird.
| Zitat: |
| Eine Sache habe ich noch gar nicht verstanden, wie füge ich meine eigenen Fragen dem Quiz zu (besser den Labels)?? |
Wie ich schon mehrmals erwähnte, musst Du Dir dafür ein Miniprogramm schreiben. Aber das kann man (wenn man es nicht zu komfortabel macht) ziemlich einfach machen. Und Du musst es ja auch nicht alleine schreiben. :wink:
MfG,
Peter
01Detlef - Mo 13.01.03 14:48
hallo,
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| TYPE TFrage = RECORD Frage : String; a,b,c,d : String; antwort : Char; END;
var Frage = array[0..15] of TFrage;
if nummer = 0 THEN TFrage[0].Frage:= 'Was ist ...'; TFrage[0].a:='...'; TFrage[0].b:='..'; TFrage[0].c:='..'; TFrage[0].d:='..'; TFrage[0].antwort:=a; if nummer = 1 THEN ........ // den Antworten a..d sind doch schon die Labels zugeordnet mit der with do anweisungen?? |
Das ist jetzt meine idee das array zu füllen!
Muss jetzt die datei, wo das hinein soll ein neues formular sein oder wie mache ich das?
Danke Detlef
Christian S. - Mo 13.01.03 16:58
1. Die IF-Anweisungen erscheinen mir nicht sehr sinnvoll. Die kann man auch weglassen.
2. Selbst wenn sie sinnvoll wären, würden dem ganz ein paar BEGINs und ENDs gut tun.
Was den Kommentar im Quelltext anbelangt: mit der with..do-Anweisung werden die Labels genau dann mit neuem Text gefüllt, wenn eine richtige Antwort gegeben wurde und auch nur dann. Der Text, der dabei in die Labels "eingefüllt" wird, wird dabei aus dem Array gelesen.
Das Füllen des Arrays, wie Du es machst, ist natürlich möglich. Aber es ist nicht sehr flexibel. Wenn neue Fragen in ein Quiz eingebunden werden sollen, musst Du jedesmal das Programm neu kompilieren. Das ist unkomfortabel.
Wenn Du es trotzdem so machen willst: wenn Du den Quelltext von Dir korrigierst, dann gehört er in das OnCreate-Ereignis der Form.
MfG,
Peter
01Detlef - Mo 13.01.03 17:39
OK, also das ist eine Möglichkeit, aber eine anfängerhafte!
Im moment weiss ich noch nicht, wie ich das mit der datei einlesen und den array da einbringen machen soll, deswegen war ich schon glücklich, dass ich diese methode gefunden habe*G*.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| VAR my_file : File of TFrage; begin SetLength(Frage,0); //Array 'Frage' soll am Anfang 0 Datensätze enthalten AssignFile(my_file,'jauch.dat'); //Weise der Datei den Dateinamen zu {$I-} //Fehlermeldung "ausschalten" Reset(my_file); //Datei öffnen {$I+} //Fehlermeldung "einschalten" IF IOResult=0 then begin //Wurde die Aktion korrekt ausgeführt? while not eof(my_file) do //Solange das Ende der Datei nicht erreicht wurde... begin SetLength(frage,Length(frage)+1); //Ergänze das Array "Frage" um einen Datensatz Read(my_file,frage[High(frage)]); //Lese den gerade erzeugten Datensatz aus der Datei end; CloseFile(my_file); //Datei wieder schließen end; end; |
Dieser obige Code läd die Fragen und Antworten aus meinem Array!
Der andere ode, der die Fragen speichert, müssen da die Zuweisungen erfolgen, sprich das array füllen? Aber muss ich das Array dort nicht auch so deklarieren, wie ich das im letzten Posting gesagt habe??
Danke Detlef
Christian S. - Mo 13.01.03 18:08
| Zitat: |
| Dieser obige Code läd die Fragen und Antworten aus meinem Array! |
Nein. Wie an der Kommentaren im Quelltext unschwer zu erkennen ist, lädt dieser Code Daten aus einer Datei in Dein Array. Wenn Du es so machst, wie Du es in Deinem vorigen Posting vorgeschlagen hast (die "Anfängermethode" :wink: ), ist dieser Quelltext nicht nötig. Wozu noch etwas aus einer Datei laden?
| Zitat: |
| Der andere ode, der die Fragen speichert, müssen da die Zuweisungen erfolgen, sprich das array füllen? |
Von welchem anderen Code sprichst Du? Von Deinem zuletzt geposteten oder von dem Code, den ich geschrieben habe?
| Zitat: |
| Aber muss ich das Array dort nicht auch so deklarieren, wie ich das im letzten Posting gesagt habe?? |
Das Array muss auf jeden Fall global deklariert werden, damit alle Prozeduren / Funktionen darauf zugreifen können.
MfG,
Peter
01Detlef - Fr 17.01.03 17:24
hallo,
ich habe jetzt mal zum testen versucht das array "auf meine art" zu füllen,
doch nun nach dem compilieren zeigt das from weder fragen noch den Button an?????
also das keine Fragen angezeigt werden, leigt vielleicht daran, dass die nummer nicht übergeben wird??
Quelltext
1:
| Label_Frage.Caption:=Frage[nummer].Frage; |
im array habe ich das so gemacht:
Quelltext
1:
| TFrage[0].Frage:= 'Was ist ...'; |
Hast du eine Idee?
Danke Detlef
Christian S. - Fr 17.01.03 18:05
Kannst Du evtl. noch was mehr Quelltext posten? Auf jeden Fall aber mal eine Info, wo der von Dir gepostete Quelltext aufgerufen wird.
01Detlef - Fr 17.01.03 19:00
natürlich!
also,
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var Frage array[0..14] of TFrage; // global gespeichert
TFrage[0].Frage:= 'Was ist ...'; TFrage[0].a:='...'; TFrage[0].b:='..'; TFrage[0].c:='..'; TFrage[0].d:='..'; TFrage[0].antwort:=a; // in oncreate Prozedur
Label_Frage.Caption:=Frage[nummer].Frage; // in der buttonprozedur, mit den zwei versuchen verbunden |
ich hoffe das reicht, wenn nicht musste dich melden!
Christian S. - Fr 17.01.03 19:20
Und das akzeptiert er so? Das wundert mich. Denn der Befehl
Quelltext
1:
| TFrage[0].Frage:='...'; |
ergibt eigentlich keinen Sinn, denn damit weist Du nicht einem Element des Arrays einen Wert zu, sondern sprichst mit TFrage den Datentyp an. Was TFrage[0] in dem Zusammenhang sein könnte, ist mir völlig schleierhaft. Auf jeden Fall sollte es heißen:
Quelltext
1:
| Frage[0].Frage:='...'; |
Und bei den übrigen natürlich ebenfalls das 'T' weg.
An den richtigen Stellen steht das ganze meiner Meinung schon. Interessant wäre es noch, welche Werte Du in OnCreate und dem ButtonClich der Variable 'nummer' zuweist. Im OnCreate solltest Du der 'nummer' den Wert zuweisen und beim ButtonClick jedesmal, wenn Du eine neue Frage anzeigen willst, um eines erhöhen,
bevor Du die Labels neu befüllst.
MfG,
Peter
01Detlef - Sa 18.01.03 14:44
also,
wenn ich das T von TFrage wegnehme, weiss er nicht mehr was a..d sein soll und zeigt immer Fehler an!
(das verstehe ich nicht, dein argument das t wegzulassen ist logisch!)
z.B
Quelltext
1:
| Frage[0].Antwort:=a;// er weiss nicht was a ist! muss es vielleicht 'a' heißen? |
Und Nummer weise ich in oncreate den wert null zu und in der button-prozedur wird es um eins erhöht!
ich bin mir nicht sicher, wie das programm weiss, dass die 'nummer'
das in den Klammern ist Frage[5].Frage....; ich habe nummer nur als integer deklariert!
Danke Detlef
Christian S. - Sa 18.01.03 14:56
Dass er nicht weiß, was a ist, ist klar. Woher auch? Es ist ja nirgends definiert. Es muss wirklich 'a' heißen.
| Zitat: |
ich bin mir nicht sicher, wie das programm weiss, dass die 'nummer'
das in den Klammern ist Frage[5].Frage....; ich habe nummer nur als integer deklariert! |
Im ButtonClick muss es doch auch Frage[nummer] und nicht Frage[5] heißen. Nur im OnCreate verwendets Du "richtige" Zahlen!
MfG,
Peter
01Detlef - Sa 18.01.03 19:00
So weit ist es in ordnung, nun akzepiert der Compiler nicht die Klammern:
Quelltext
1:
| Frage[nummer].Frage... |
er möchte () diese Klammern haben?
detlef
Christian S. - So 19.01.03 12:34
Poste mal von der Prozedur, wo der Fehler kommt, den gesamten Quelltext mit Kopf und allem.
01Detlef - So 19.01.03 13:51
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| var Form1: TForm1; versuche, nummer : Integer;
procedure TForm1.Button1Click(Sender: TObject); var antwort : String; begin Antwort:= edit1.text[1]; IF antwort = TFrage[nummer].Antwort THEN BEGIN Versuche := 0; INC (nummer); Label1.Caption:= Frage[nummer].Frage; with Frage[nummer] do BEGIN Label2.Caption:=a; Label3.Caption:=b; Label3.Caption:=c; Label4.Caption:=d; END; END ELSE.. |
01Detlef - So 19.01.03 14:02
Ach der Fehler leigt glaube ich darin, dass ich das array nicht global deklariert habe?!?!?
Detlef
Christian S. - So 19.01.03 14:05
Ja! Das Array muss auf jeden Fall global deklariert werden. Woher sollten die anderen Prozeduren sonst wissen, dass es überhaupt existiert. Ach ja, in der IF-Abfrage steht noch ein "T" vor der Frage.
01Detlef - Mo 20.01.03 20:12
Also das Programm läuft jetzt, es gibt noch ein paar Problemchen, aber die werde ich versuchen zu beheben!
Nun mich reizt es trotzdem, mit dem einlesen der datei zu arbeiten!
kannste mir vielleicht mal ein paar stichwörter sagen, was ich mir mal angucken sollte, um mir das nötige wissen anzutrainieren?? Weil, wenn ich jetzt alles fragen muss, ist für keinen vorteilhaft!
Aber auf jeden Fall schon mal vielen Dank für deine Hilfe bis hier hin, ich habe dadurch viel neues gelernt!
Danke Detlef
Christian S. - Mo 20.01.03 20:21
Schön, dass es jetzt klappt.
Das Wichtigste, was Du brauchst, um die Daten in deinem Quiz einzlesen und mit einem anderen (noch zu schreibenden) Programm zu schreiben, habe ich schon mal gepostet. Das waren zwei getrennte Quellcodes für das Lesen und das Schreiben einer solchen Datei. Du solltest diese Quellcodes durchgehen und (evtl. mit der Hilfe) verstehen, was dort eigentlich passiert.
Wenn Du irgendwas nicht verstehst, kannst Du hier im Forum suchen und wenn Du dann nichts findest, einfach mal posten.
Wenn Du dann weist, wie die beiden Codes funktionieren, kannst Du Dich dran machen, sie (a) in dein Quizprogramm und (b) in das noch zu schreibende Programm einzubauen.
Wichtig: beschäftige Dich auch mal mit "dynamischen Arrays".
MfG,
Peter
01Detlef - Fr 31.01.03 15:11
hallo,
ich habe jetzt noch ein problem, wenn ich das programm starte erscheint die erste Frage nicht!?!?!?
Also:
Quelltext
1: 2: 3:
| Frage[0].Frage:='...'; Frage[0].a:='::'; .... |
Also die labels werden nicht gefüllt, die Antwort kann ich geben und komme auch zur nächsten Frage, nur halt die Frage steht nicht da??!!?
p.s an den dynamischen arrays bin ich dran
Danke Detlef
Christian S. - Fr 31.01.03 15:14
Könnte es daran liegen, dass die Fragen ja erst beim ButtonClick geladen werden (wenn die Antwort richtig war)? Der wird bei der ersten Frage aber nicht ausgeführt, deswegen wird dann das Label nicht gefüllt. Am besten schreibst Du direkt hinter den Code, in dem das Array gefüllt wird noch mal einen Code, der den Labels die erste Frage zuordnet.
MfG,
Peter
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!