# Wie mach ich am besten ne highscore mit C++



## Puepue (12. Februar 2010)

Ich arbeite ja derzeit an einem Spiel und hab jetzt so ziemlich alles was ich brauche. Eine Highscore fehlt mir aber noch.
10 Plätze würden reichen denke ich, da bin ich aber flexibel,
mehrere Spieler können auch die gleiche Punktzahl haben.

Ich hab mir schon mal bubblesort angeschaut und das scheint auch nicht so schlecht zu sein, das Problem ist aber, dass ich mir mit der Verbindung Zahl<=>Name nicht so sicher bin..

Beispiel: ich habe eine Datei geschrieben da  steht drin

200|vornamea|nachnamea
100|xy|z
150|a|qwertz

dann könnte ich das ja in PHP exploden o.ä. und die Namen gleichzeitig mit der dazugehören Punktezahl sortieren.

Andere Idee, die ich hatte:
eine Datei namen
eine Datei punkte  
=> Dann könnte man die Punkte sortieren ohne Probleme aber wie sortiere ich synchron die Namen?

Schreiben ist kein Problem, auslesen kann ich die Sachen denke ich mal auch (zumindest mit fputs).

Kennt da jemand eine Lösung, die ich als Anfänger vlt sogar verstehe?
Etwas, das direkt beim Schreiben sortiert wäre natürlich auch nicht schlecht


----------



## DarkMo (12. Februar 2010)

die daten die du ins array schreibst, kommen ja irgendwoher. und eben beim reinschreiben, kannst du ja schauen, ob der wert größer wie der kleinste is und wenn ja, gehste das array durch und bastelst es an der richtigen stelle gleich ein. musst halt den "schwanz" dann imer aufrücken un das letzte löschen, aber machbar sollte es sein. im zweifelsfalle ne liste gebaut, die du mit daten aus der datei füllst. dann kannste einfach nen neues element an der entsprechenden stelle einfügen und das letzte element schnippelste ab. spart das aufrücken.


----------



## Puepue (12. Februar 2010)

also wie ich z.b. 1 3 2 sortiere wäre damit ja klar, aber was mach ich mit den namen die müssen ja dabei stehen


----------



## DarkMo (12. Februar 2010)

naja, machst halt nen mehrdimensionales array, als vergleichskriterium kommt aber nur der punkte wert in frage. also vergleichst halt nur die punkte un nich au noch die namen.


----------



## xR4Y (12. Februar 2010)

also ich würde einfach mit 2 Arrays arbeiten welche exakt gleich groß sind eben eines mit (vermutlich) Integer Werten für Punkte und ein string array in welchem der Name steht. Würde heißen musst du wegen Punkten die Position im array tauschen musst du das gleiche auch auf das String array anwenden... oder auch mehrdimensional arbeiten, dann hättest du aber vermutlich das Problem mit Integer und String als datentyp...


----------



## DarkMo (12. Februar 2010)

hmm, stimmt, is ja kein php ^^ ich war schon zu lange auf "abwegen" >< aber in php sind arrays ja so gesehn auch nur ne art listen.


----------



## Puepue (13. Februar 2010)

Hm ich hab weder Ahnung von mehrdimensinalen Arrays noch von vectoren listen und sowas (ich mach c++ eigentlich nur wegen der schule) in php/sql würde ich das auch hinbekommen
kann vlt jemand mal einen beispielcode schreiben damit ich mir das so in etwa vorstellen kann?


----------



## Bauer87 (13. Februar 2010)

Nimm am besten eine std::list, also ne doppelt verkettete Liste. Das hat den Vorteil, dass du überall neue Leute einfügen kannst: einfach die Liste nach der niedrigsten höheren Punktzahl absuchen und dahinter einfügen.

In der Liste speicherst du am besten Objekte der folgenden Klasse:

```
class Entry{
private:
    std::string name;
    unsigned int points;
public:
    Entry(std::string str, unsigned int uin){
        name = str;
        points = uin;
    }
    unsigned int getPoints(){
        return points;
    }
    std::string getName(){
        return name;
    }
}
```

(Ich gehe davon aus, dass du die Beispiele zur Liste selber lesen kannst. Eine Anwendung der Art sollte eigentlich in jeder Doku stehen.)

Zum speichern: Das machst du entweder als Text, also per fstream. Du packst also nacheinander alles in eine Textdatei. Dann musst du aber darauf achten, dass dein Feldtrenner nicht in den Namen vorkommt: Wenn du „Name; Punktzahl; Name; Punktzahl“ speicherst und sich plötzlich jemand „Foo;Bar“ nennt, oder den Namen frei lässt, darf das nicht angenommen werden.

Daneben gibt es auch die Möglichkeit, die ganze Liste binär in eine Datei zu schreiben. Das habe ich aber noch nicht gemacht, müsste das erst mal selber ausprobieren.


----------



## bingo88 (13. Februar 2010)

Binär ist natürlich dann für niemanden außerhalb mehr lesbar, musst du also dir gut überlegen, ob du das möchtest.

Ich weiß atm nicht, ob std::string was dafür mitbringt, normale C-style Strings (also char-Arrays) kann man aber in folgender Form speichern:
<Länge><Text>. Dann liest du halt zuerst nen int für die Länge und weist danach, wie viel Text du noch lesen musst.


----------



## Bauer87 (13. Februar 2010)

Der char kann afaik nur seine 256 verschiedene Zeichen. Wenn jemand da André eingeben will, ist der std::string schon angenehmer.


----------



## bingo88 (13. Februar 2010)

std::string speichert meines wissens aber auch kein Unicode (std::wstring schon). Du kannst auch erst den int schreiben und dann über Streamoperatoren den String, es ist halt nur wichtig, dass du weist, wie lang der String ist.


----------



## Puepue (13. Februar 2010)

Ich hab jetzt etwas umgesattelt und lasse nur noch die hächste Zahl abspeichern und ausgeben..

Problem:

```
pFile = fopen ("higpoints.hig","a");
	 if (pFile==NULL) perror ("Error opening file");
	 else
	 {
		// Schreibe Punkte ans Ende der Sammel-Datei
                //Spieler.punkte ist ein int
		if (Spieler1.punkte > 0)                                    
		{
			fputc (Spieler1.punkte,pFile);      // gibt komische Sonderzeichen in der Datei aus
			fprintf (pFile, itoa(i,Spieler1.punkte,4)); // gibt Fehlermeldung aus int kann nicht in char konvertiert werden
			fputc ('\n',pFile); // das klappt

		}
```


```
phighest = fopen ("highest.hig","r");
biggest = fgetc ( phighest );				// Bisherige hoechste Zahl auslesen
cout << "Der bisher hoechste Punktestand ist " << biggest << endl;
fclose (phighest);
```
in highest.hig steht 0, die ausgabe ist dann immer
Der bisher hoechste Punktestand ist 48

kann mir jemand irgendeine Funktion nennen die integer ein und auslesen kann?


Ich poste hier mal den kompletten Code-Part, vielleicht ist da ja nur einfach ein Fehler versteckt:

```
FILE * pFile;
	 FILE * phighest;
	 
		
	 

	 int biggest = 0;
	 char zahl1[5];
     phighest = fopen ("highest.hig","r");
		  biggest = fgetc ( phighest );				// Bisherige hoechste Zahl auslesen
		 cout << "Der bisher hoechste Punktestand ist " << biggest << endl;
	 fclose (phighest);

	 pFile = fopen ("higpoints.hig","a");
	 if (pFile==NULL) perror ("Error opening file");
	 else
	 {
		// Schreibe Punkte ans Ende der Sammel-Datei
		if (Spieler1.punkte > 0)
		{
			fputc (Spieler1.punkte,pFile);
			//fprintf (pFile, itoa(i,Spieler1.punkte,4));
			fputc ('\n',pFile);

		}
		if (Spieler2.punkte > 0)
		{
			fputc (ConvertToChar(Spieler2.punkte),pFile);
		}
		if (Spieler3.punkte > 0)
		{
			fputc (ConvertToChar(Spieler3.punkte),pFile);
		}
		if (Spieler4.punkte > 0)
		{
			fputc (ConvertToChar(Spieler4.punkte),pFile);
		}
		
		
		fclose (pFile);		// Schliesse Sammeldatei

		
	    
		// Speichere groessten Wert ab
		if (Spieler1.punkte > biggest)
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler1.punkte , phighest );
			fclose (phighest);
		}
		if (Spieler2.punkte > biggest)
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler2.punkte , phighest );
			fclose (phighest);
		}
		if (Spieler3.punkte > biggest)
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler3.punkte , phighest );
			fclose (phighest);
		}
		if (Spieler4.punkte > biggest)
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler4.punkte , phighest );
			fclose (phighest);
		}

		phighest = fopen ("highest.hig","r");
		  biggest = fgetc ( phighest );				// Bisherige hoechste Zahl auslesen
		 cout << "Der derzeitige hoechste Punktestand ist " << biggest << endl;
		fclose (phighest);

		
	 }
```


----------



## Puepue (14. Februar 2010)

Hat sich schon erledigt 

Jetzt klappts 


```
int biggest = 0;
	 char zahl1[5];
     phighest = fopen ("highest.hig","r");
		  biggest = fgetc ( phighest );				// Bisherige hoechste Zahl auslesen
		 cout << "Der bisher hoechste Punktestand ist " << biggest << endl;
	 fclose (phighest);

	 pFile = fopen ("higpoints.hig","a");
	 if (pFile==NULL) perror ("Error opening file");
	 else
	 {
		// Schreibe Punkte ans Ende der Sammel-Datei
		if (Spieler1.punkte > 0)
		{
			fputc (Spieler1.punkte,pFile);
			//fprintf (pFile, itoa(i,Spieler1.punkte,4));
			fputc ('\n',pFile);

		}
		if (Spieler2.punkte > 0)
		{
			fputc (ConvertToChar(Spieler2.punkte),pFile);
		}
		if (Spieler3.punkte > 0)
		{
			fputc (ConvertToChar(Spieler3.punkte),pFile);
		}
		if (Spieler4.punkte > 0)
		{
			fputc (ConvertToChar(Spieler4.punkte),pFile);
		}
		
		
		fclose (pFile);		// Schliesse Sammeldatei

		
	    
		// Speichere groessten Wert ab
		if (Spieler1.punkte >= ConvertToInteger(biggest) && Spieler1.punkte >= Spieler2.punkte && Spieler1.punkte >= Spieler3.punkte && Spieler1.punkte >= Spieler4.punkte )
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler1.punkte , phighest );
			fclose (phighest);
		}
		if (Spieler1.punkte >= ConvertToInteger(biggest) && Spieler2.punkte >= Spieler1.punkte && Spieler2.punkte >= Spieler3.punkte && Spieler2.punkte >= Spieler4.punkte )
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler2.punkte , phighest );
			fclose (phighest);
		}
		if (Spieler3.punkte >= ConvertToInteger(biggest) && Spieler3.punkte >= Spieler2.punkte && Spieler3.punkte >= Spieler1.punkte && Spieler3.punkte >= Spieler4.punkte )
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler3.punkte , phighest );
			fclose (phighest);
		}
		if (Spieler3.punkte >= ConvertToInteger(biggest) && Spieler4.punkte >= Spieler3.punkte && Spieler4.punkte >= Spieler1.punkte && Spieler4.punkte >= Spieler2.punkte )
		{
			phighest = fopen ("highest.hig","w");
			fputc ( Spieler4.punkte , phighest );
			fclose (phighest);
		}

		phighest = fopen ("highest.hig","r");
		  biggest = fgetc ( phighest );				// Bisherige hoechste Zahl auslesen
		 cout << "Der derzeitige hoechste Punktestand ist " << biggest << endl;
		fclose (phighest);

		
	 }
```


----------



## Bauer87 (14. Februar 2010)

Nur so als Anmerkung: Hattest du nicht von C++ gesprochen? Du benutzt dafür recht viele C-Funktionen (fopen, etc.) und insgesamt könnte das auf den ersten Blick sogar reiner C-Code sein…

Aber toll, dass du es geschafft hast.


----------



## Puepue (14. Februar 2010)

Hmmm also mit Visual Studio c++ funktionierts o0
Aus der Schule kenn ich auch nur, dass man sowas da macht:


```
// Zum Schreiben 
	ofstream fout ("text.txt");
	fout << "Hallo Welt";
	fout << endl << zahl;
	fout.close();
```

aber da fehlen mir so Parameter wie "w" oder "a" - also Datei vorm befüllen löschen etc.



Ich habe das Spiel mal hochgeladen:

FileBase.to - Deinem persnlichen High-Speed Multimedia-Hoster


wichtig ist, dass man vorher den ganzen Ordner entpackt, weil die highest.hig vorhanden sein muss.

Vielleicht hat ja noch jemand ne gute Idee die man noch schnell einbauen könnte?


----------



## Bauer87 (15. Februar 2010)

r, w, a heißen „read”, „write“, „append“ und heißen lesen, schreiben, einfügen. Das sollte mit dem fstream-Objekt nicht mehr nötig sein, weil man den Pointer in der Datei ja beliebig setzen kann. Zum „vorher löschen“, wie du es nennst, schreibt man einfach ab dem Dateianfang und für das Anhängen sollte man ihn nach ganz hinten bewegen können. Siehe Doku:

fstream - C++ Reference

Tante Edith meint: Ich würde das Spiel gern mal anschauen, habe aber kein Windows. Wen der Code nicht zu arg von Windows abhängig ist, würde ich mich auch bereit erklären, den zu portieren.


----------



## bingo88 (17. Februar 2010)

Bauer87 schrieb:


> Tante Edith meint: Ich würde das Spiel gern mal anschauen, habe aber kein Windows. Wen der Code nicht zu arg von Windows abhängig ist, würde ich mich auch bereit erklären, den zu portieren.


Diese komischen funktionenen a la _kbhit() könnten das schwierig gestalten (wenn's denn noch drinnen is, hab's mir net angesehn. Schließe das jetzt aus dem letzten Topic mit dem Integer-Problem)...


----------



## Puepue (20. Februar 2010)

Ja ist ziemlich Windowsabhängig.. 
Musste das Spiel letzten Montag abgeben mal schaun was es für ne Note wird


----------



## nahkillo94 (22. Februar 2010)

kannst du es nochmal woanders hochladen, bei megaupload oder so? irgendwie geht der download dort nicht. wollte es mir auch mal angucken.


----------



## Puepue (28. Februar 2010)

Schau mal hier:
RapidShare: 1-CLICK Web hosting - Easy Filehosting

die "highscore" funktioniert nur, wenn du  den Ordner vorm Ausführen entpackst
http://www.megaupload.com/?d=WEMQJMR8


----------



## Puepue (12. Januar 2011)

War eh gerade dabei ein paar Dateien bei Megaupload zu "archivieren"  usw. - dachte ich grab ich das hier mal wieder aus und schreib nen Link  hin: MEGAUPLOAD - The leading online storage and file delivery service


----------



## Zappzarrap (12. Januar 2011)

Kannst du dazu mal den Code uppen, würd mir das gern mal anschauen


----------

