Entwickler-Ecke
Sonstiges (Delphi) - Highscore für ein Spiel
Markus2000 - Di 08.02.05 16:03
Titel: Highscore für ein Spiel
Hallo,
ich bin derzeit ein kleines Projekt für meinen Informatikkurs (Stufe 13 eines Gymnasiums) am programmieren. Ich mache einen kleinen "Nachbau" des Spiels Moorhuhn.
Bei diesem Spiel wird nach Spielende eine Auswertung der Treffer und ein digitaler "Pokal" angezeigt.
Ich möchte nun im Anschluss an diese "Siegerehrung" den Namen des Spielers (der wird vor "Pokalvergabe" abgefragt) und seine Punktezahl in eine Highscoreliste eintragen, welche gespeichert werden soll.
Leider stehen mir mit Delphi 6 Standard keine Datenbank-Komponenten zur Verfügung, wesshalb ich das Problem anders angehen muss.
Ich habe mir gedacht, dass es am sinnvollsten wäre, die Daten in eine Textdatei zu speichern?!
Doch wie speichere ich meine zwei Variablen (Name und Punkte) in die Textdatei und vor allem: wie lese ich sie aus und sortiere sie nach Punkten, denn es soll ja eine Highscore sein!?
Ich wäre euch sehr dankbar für einige Tipps!
danke
Markus
retnyg - Di 08.02.05 16:08
wie wäre es wenn du in die textdatei immer abwechselnd name, nächste zeile, punktezahl reinschreibst.
mit einer zählvariable mod 2 kannst dann schauen ob er die ungeraden oder geraden zeilen einliest und je nachdem mit dem eingelesenen wert verfahren.
uall@ogc - Di 08.02.05 16:17
ich würde ja nen record verwenden...
Delphi-Quelltext
1: 2: 3: 4:
| type blub = packed record name: string[32]; punkte: integer; end; |
F34r0fTh3D4rk - Di 08.02.05 16:39
ich würde ne ini machen die ich erstmal auslese gucke wo das ergebnis reinpasst und es dann da hinbringen, oder ggf die ini neuschreiben, also mit inis würde es gehn man müsste nur noch überlegen wie genau :?
Karlson - Di 08.02.05 16:51
Möglichkeiten um die Liste zu speichern gibts tausende, wobei die eleganteste wohl der Record wäre.
Aber warum so kompliziert? Ihr müsst dran denken, dass die Liste auch noch sotiert werden muss, und da hat die TSTringList schon eine Methode dabei. Einfach stringlist.sort, dann in umgekehrter Reihenfolge in den Record oder die Ini schreiben und schon hat man eine geordnete HighScoreliste.
Markus2000 - Di 08.02.05 16:59
Hi!
Vielen Dank für eure zahlreichen Antworten!
@Karlson:
Ich habe mir deine Anleitung durchgelesen und probiere sie gerade aus. Es wird jedoch leider keine Datei abgespeichert und es wird auch in der listbox nicht sortiert.
Wäre es denn mit records oder ini-datei einfacher zu handhaben?
Du schreibst:
"Einfach stringlist.sort, dann in umgekehrter Reihenfolge in den Record oder die Ini schreiben und schon hat man eine geordnete HighScoreliste."
aber wie geht das genau. Wie bekomme ich die einträge in umgekehrter Reihenfolge in die Stringlist? Und wie speichere ich alles ab und lese es wieder ein?
Danke
markus
Karlson - Mi 09.02.05 00:52
Du machst was falsch ;)
Der Code in dem Tutorial funktioniert zu 100%.
Poste mal was du bis jetzt hast.
Die von dir angesprochenen Fragen, werden im Faq Beitrag übrigens beantwortet!
Aber nochmal verständlicher und zum mitschreiben ;)
Wir wollen:
- Eine StringList, in der die HighScore Daten gespeichert sind. Warum...?
- ...Weil die TStringList über die Procedure Sort verfügt.
Was mach Sort konkret:
Quelltext
1: 2: 3:
| 5000 Karlson 3431 Karlson 3432 Soundso |
Wenn wir die Sort Prozedure aufrufen, sieht die Liste so aus:
Quelltext
1: 2: 3:
| 3431 Karlson 3432 Soundso 5000 Karlson |
Okay, das macht sort, dazu später mehr.
Wie bekommen wir den Punktestand und den Namen des Spieler in diese StringList?
So:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| var H : TStringList; Punkte, NAme : String; begin Punkte := 5000; Name := 'Karlson'; H := TSTringList.Create; H.add(Punkte + ' ' + Name); end; |
Nun haben wir eine Liste mit sagen wir mal 3 Einträgen.
Dann können wir jetzt auch erstmal den Sort Befehl aufrufen:
Nun ist unsere Liste sortiert, aber halt leider falschrum. In einer HighScore Liste soll schließlich der beste oben stehen. Das können wir aber berücksichtigen, wenn wir die Liste anzeigen lassen. z.B. in einer ListBox.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| var i : integer; begin ListBox1.Items.Clear; for i := H.Count-1 downto 0 do ListBox1.items.add(H[i]); end; |
Was machen wir hier? Die StringList ist sowas wie ein liniertes Blatt Papier. Jede Zeile hat eine feste Zuordnungszahl. Etwas verwirrend ist, dass die erste Zeile die Zuordnungszahl 0 hat.
Also, wir weissen der Zählvariable i an, bei der letzen Zeile unseres Blatts (die Zeilenanzahl bekommen wir mit StringList.count, da wir bei 0 anfangen zu zählen, ist die letze Zeile natürlich StringList.Count-1) anzufangen, diese Zeile in die ListBox einzutragen. da die Letze Zeile der sortierten StringList den höchsten Wert hat (nicht vergessen, es wurde von unten nach oben sortiert) muss sie als erstes in die Listbox eingeschrieben werden.
Eines noch:
Es gibt ein kleines Problem beim sortieren der Liste:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| 3 6 4 5 1 11
Daraus wird:
1 11 3 usw. |
Die Sort funktion, sortiert leider
Chargebunden. Das bedeutet, dass sie nur den ersten Buchstaben in betracht zieht. Sie intressiert es folglich nicht, dass 11 eigentlich grösser als 3 ist. Sie intressiert nur, dass die erste Ziffer der gesamten Linie kleiner als drei ist.
Das ganze umgehen wir, indem wir alle Punktzahlen auf die gleiche Zeichenlänge bringen.
Bei gleichen Ziffern, wir nämlich immer die nächste genommen, klingt kompliziert, das hier sollte verständlicher sein:
Quelltext
1: 2: 3: 4: 5: 6: 7:
| 01 03 04 05 08 11 40 |
So kommt die Sortierfunktion nicht mehr durcheinander.
Codegebunden machen wir das so, dass wir direkt beim eintragen des Namens und der dazugehörigen Punktzahl in die StringListe den Punktwert auffüllen.
Delphi-Quelltext
1: 2: 3:
| while length(punkte) > 5 do Punkte := '0' + Punkte; Highscore.add(Punkte + ' ' + Name); |
Das ganze ist noch ausführlicher im Faqbeitrag erklärt, also lesen ;)
Markus2000 - Mi 09.02.05 18:53
Hey Karlson,
vielen Dank für deine Mühe!
Hab noch ein wenig rumprobiert und es klappt soweit ganz gut.
Doch leider wird nichts abgespeichert....
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| HighScorePfad := ('c:\MeineHighScoreDatei.dat'); try HighScore := TStringList.Create; finally if FileExists(HighScorePfad) then HighScore.LoadFromFile(HighScorePfad) else begin HighScore.Add('00 Unknown'); HighScore.Add('00 Unknown'); HighScore.Add('00 Unknown'); |
^^ So sieht mein OnCreate aus. Sobald keine Datei existiert, sollte ja eine erstellt und gespeichert weden, aber dafür ist ja kein Befehl da. Wie speichere ich die Highscoreliste?
Danke
markus
Moderiert von
raziel: Code- durch Delphi-Tags ersetzt.
Karlson - Mi 09.02.05 18:55
Wie man StringList speichert steht in der OH... ;)
Naja: highscore.savetofile('c:\hs.dat')
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 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!