Autor Beitrag
Markus2000
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 08.02.05 16:03 
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
Karlson
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: Di 08.02.05 16:07 
Hallo,

Ich habe dazu einen FAQ Beitrag verfasst.
Schau mal hier
www.delphi-forum.de/...alisieren_35129.html

Schau mal ob du's hinbekommst so.
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Di 08.02.05 16:17 
ich würde ja nen record verwenden...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
type blub = packed record
               name: string[32];
               punkte: integer;
            end;
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: 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:

ausblenden Quelltext
1:
2:
3:
5000   Karlson
3431   Karlson
3432   Soundso


Wenn wir die Sort Prozedure aufrufen, sieht die Liste so aus:

ausblenden 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
 H : TStringList; //WICHTIG: Die StringList bitte in den Globalen Variablen deklarieren
 Punkte, NAme : String
begin
 Punkte := 5000;
 Name := 'Karlson';
 H := TSTringList.Create; //Wir erstellen eine neue virtuelle Liste
 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:

ausblenden Delphi-Quelltext
1:
 H.Sort; //Das wars schon :-)					


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.

ausblenden 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:

ausblenden 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:

ausblenden 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.

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: 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....

ausblenden 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 user profile iconraziel: Code- durch Delphi-Tags ersetzt.
Karlson
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: Mi 09.02.05 18:55 
Wie man StringList speichert steht in der OH... ;)

Naja: highscore.savetofile('c:\hs.dat')