# Highscoreliste mit Java erstellen



## gavanaa (9. Mai 2005)

Hi an alle Java-Götter und (verkannte und nichtverkannte) Programmierer da draußen,

Hab folgendes Aufgabe/Problem. Wir sollen für die Schule ein kleines (ohhh mann, ich möcht nie was großes programmmieren!) EinMalEins-Quiz programmieren [also in der Art: a*b=?, das ganze, z.b. 10 durchgänge, und dabei soll die Zeit gestoppt werden].

So, das hab ich bis dahin auch mehr oder weniger glorreich gelöst  ;-) (also das Programm läuft zwar noch nicht ganz soo flüssig, wie es soll, aber das ist es nur noch eine Sache von _[((wenigen))]_ Handgriffen, aber ihr könnt ich euch darauf gefasst gemachen, dass womöglich noch mehr Fragen hier reindonnern!), was ich jetzt noch aber ganz gern reinmachen würde, wäre ein schöne Highscoreliste, wo man am Ende seinen Namen reintippt und wo alle dann schön nach Endzeit (wenn man einen Fehler gemacht hat, kommt ein Frage dazu. Also man muss am Ende genau 10 richtige Antworten haben) gereiht hinterandere aufgelistet werden (top10 würde ja auch reichen...).

Das ganze Programm hab ich als *Applikation * gemacht (*nicht Applett!*)

p.s.: noch etwas nebensächliches, gibt es ein Programm, dass einen Quellcode automatisch in ein Flussdiagramm umwandelt. Denn darauf hab ich echt kein Bock mehr, ganz zu schweigen von der Zeit die mir vermutlich heut Abend dazu fehlen wird, DENN MORGEN IST SCHON ABGABEAHHHHHHH


Schonmal im vorraus:
Vielen Dank für eure barmherzige großzügige Hilfe!


----------



## Haruka (9. Mai 2005)

ich liebe fragen bei denen man die fragen suchen muss 

du willst also einen einfachen highscore, richtig?

mach dir doch einfach ein 2d-array mit 10 feldern und pack da die punktzahlen und die namen rein

String score[][] = new String[10][2];
score[0][0] = "100"; score[0][1] = "haruka";

wenn ein spiel zuende ist:
- vergleich die neue punktzahl mit dem topscore und dem 10ten platz
- liegt deine punktzahl dazwischen, gibts nen neuen score
- liegt deine punktzahl überm einser, hast du nen neuen rekord
- liegt deine punktzahl unterm 10ten platz - vergiss es ^^
- hast du nen neuen score, durchlaufe das array von vorne und suche nach der stelle, wo der neue score grösser is als der letzte platz, aber kleiner als der nächste
- pack den score da rein
- natürlich hast du dir gemerkt, was vorher in dem feld für ein wert stand 
- pack jenen wert in die nächst tiefere position im score
- mach das so lange bis zum array-ende
- position 10 vergisst du einfach - top11 gibts ja nicht

beim laden und beim beenden des spiels lässt du dieses array einfach laden/speichern. dafür reicht eine text-datei und von mir aus auch eine xml-datei.


----------



## gavanaa (9. Mai 2005)

erstmal schonmal danke,

Mein Problem liegt aber eigentlich mehr in der Richtung, dass er die Datei dann richtig liest und richtig beschreibt...


----------



## hpvw (9. Mai 2005)

Als einfaches Beispiel, als Bonus für eine Übungsaufgabe, würde ich folgendes machen:
Du erstellst Dir eine Klasse "HighscoreEintrag", welche Comparable implementiert. Diese ist in der Lage einen Punktestand, double (Zeit) oder int (Punkte) und einen Namen zu speichern. Dem Konstruktor dieser Klasse übergibst Du wahlweise Namen und Punktestand (alter Eintrag) oder nur den Punktestand (frisch erreichte Score). In dem letzten Fall wird der User direkt im Konstruktor nach seinem Namen gefragt.
Dann machst Du eine Klasse "HighscoreListe", die von ArrayList oder Vector erbt und erweiterst sie um Speicher-, Lade- und Sortierfunktionen.
Dazu würde ich dem ganzen noch eine Funktion zur Ausgabe verpassen. Entweder in einer eigenen Klasse, die von Frame oder JFrame (oder das entsprechende in SWT, wenn ihr mit SWT arbeitet) erbt und im Konstruktor besagte HighscoreListe übergeben bekommt oder einfach in einer Funktion in der HighscoreListe, die alle Highscores über die Konsole ausgibt.
Hättest Du mehr Zeit ginge das sicherlich eleganter, zum Beispiel mit strikter Trennung von Daten und Präsentation, aber im Angesicht des Zeitdrucks kann man sich überlegen, ob man sogar auf's Speichern verzichtet.

Links:
Collections.sort(java.util.List)
Comparable
FileWriter
FileReader


Gruß hpvw


----------



## Haruka (10. Mai 2005)

gavanaa hat gesagt.:
			
		

> Mein Problem liegt aber eigentlich mehr in der Richtung, dass er die Datei dann richtig liest und richtig beschreibt...


 
Gut, hab ich aus deine Fragestellung nich rauslesen können...
Hast du es dennoch rechtzeitig hinbekommen?



			
				hpvw hat gesagt.:
			
		

> Du erstellst Dir eine Klasse "HighscoreEintrag", welche Comparable implementiert. Diese ist in der Lage einen Punktestand, double (Zeit) oder int (Punkte) und einen Namen zu speichern.


 
Mh, ist "Comparable" dann das was man unter cpp noch "struct" genannt hätte?


----------



## hpvw (10. Mai 2005)

Haruka hat gesagt.:
			
		

> Mh, ist "Comparable" dann das was man unter cpp noch "struct" genannt hätte?


Sicher kann ich Dir das nicht sagen, aber nach einem kurzen Überblick des Google-Suchergebnisses nach struct: Nein.
Comparable ist ein Interface, welches Dich zwingt, eine Vergleichsfunktion zu implementieren. Der Funktion wird ein Object übergeben, welches mit der eigenen Instanz verglichen werden soll. Diese Funktion ist folgendermaßen zu implementieren:
In diesem Fall prüfe man zunächst mit instanceof, ob es sich um einen "HighscoreEintrag" handelt. Schlägt das fehl, werfe man eine ClassCastException. Dann vergleiche man die gespeicherten Punkte und gebe entsprechend -1 (eigene Instanz ist kleiner), 0 (eigene Instanz ist gleich der Übergebenen) oder 1 (eigene Instanz ist größer) zurück. Die Reihenfolge ist hier ggf. umzukehren, da eine Highscoreliste i.d.R. absteigend sortiert ist.
Diese Methode wird von Collections.sort(java.util.List) aufgerufen, um die Elemente beim Sortieren zu vergleichen.

Gruß hpvw


----------



## gavanaa (10. Mai 2005)

Hallo,

so da bin ich wieder. Erstmal vielen Dank für eure Antworten!

@hpvw: auch nah fünfmaligen durchlesen, hatte ich immernoch keinen genauen Überblick wie ich das realisieren sollte (die Ursache liegt definitiv bei mir!) . 
Da scheint die Lösung von haruka etwas leichter zu sein (vielleicht ist sie etwas komlpizierter, aber auch für einen relativen Anfänger einfacher zu verstehen...), gestern hatte ich das beim besten Willen nicht mehr geschafft, den ganzen Spass zu realissiern, aber der Lehrer hat es mir erlaubt das Programm etwas später abzuliefern (heute?/morgen?).
Naja, dann mach ich mich mal nochmal an die Highscore ran


----------



## gavanaa (10. Mai 2005)

ohh mann, ich kriegs einfach nicht hin,
hänge gerade am Lesen und Schreiben der Datei (ich kriegs einfach nicht zeilenweise hin)....
Ausserdem funktioniert das Hauptprogramm inzwischen auch nciht mehr so wie es soll......

Ach was solls, für heute reichts mir echt!


----------



## hpvw (10. Mai 2005)

Wenn Du die Array-Variante nimmst, solltest Du Dich auch in Comparable reinarbeiten (das ist wirklich einfacher, als Du denkst) und mitArrays.sort(java.lang.Object[]) sortieren, bevor Du Deine eigene Sortierfunktion schreibst. Hier mal ein kurzes Beispiel:

```
/*
 * Created on 10.05.2005
 *
 */
package sortingArrays;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

/**
 * @author Hans Peter von Welt
 *  
 */
public class SortArray {

	private class HighscoreEintrag implements Comparable {
		private String name;

		private double punkte;

		public HighscoreEintrag(String name, double punkte) {
			this.name = name;
			this.punkte = punkte;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Comparable#compareTo(java.lang.Object)
		 */
		public int compareTo(Object o) {
			HighscoreEintrag hE = (HighscoreEintrag) o;
			if (this.punkte > hE.getPunkte()) {
				return 1;
			} else if (this.punkte < hE.getPunkte()) {
				return -1;
			}
			return 0;
		}

		public String getName() {
			return name;
		}

		public double getPunkte() {
			return punkte;
		}

		public String toString() {
			return this.name + ": " + this.punkte;
		}
	}

	public SortArray() {
		HighscoreEintrag[] highscore = new HighscoreEintrag[10];
		File f = new File("hs.txt");
		if (f.exists()) {
			try {
				FileReader fR = new FileReader(f);

				char[] c = new char[(int) f.length()];
				fR.read(c);
				String s = new String(c);
				String[] entrys = s.split("\n");
				for (int i = 0; i < entrys.length; i++) {
					if (i < 10) {
						String[] entry = entrys[i].split(":");
						highscore[i] = new HighscoreEintrag(entry[0], Double
								.parseDouble(entry[1]));
					}
				}
				fR.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			highscore[0] = new HighscoreEintrag("a", 10);
			highscore[1] = new HighscoreEintrag("b", 90);
			highscore[2] = new HighscoreEintrag("c", 55);
			highscore[3] = new HighscoreEintrag("d", 5);
			highscore[4] = new HighscoreEintrag("e", 20);
			highscore[5] = new HighscoreEintrag("f", 50);
			highscore[6] = new HighscoreEintrag("g", 40);
			highscore[7] = new HighscoreEintrag("h", 80);
			highscore[8] = new HighscoreEintrag("i", 30);
			highscore[9] = new HighscoreEintrag("j", 70);
		}
		Arrays.sort(highscore);
		for (int i = 0; i < highscore.length; i++) {
			System.out.println(highscore[i]);
		}
		try {
			FileWriter fW = new FileWriter(f);
			for (int i = 0; i < highscore.length; i++) {
				if (i< highscore.length -1) {
					fW.write(highscore[i].toString()+"\n");
				} else {
					fW.write(highscore[i].toString());
				}
			}
			fW.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		new SortArray();
	}
}
```
Wenn Du sowas in der Art übernimmst, solltest Du HighscoreEintrag allerdings als eigenständige und nicht als innere Klasse machen  Das habe ich nur gemacht, damit es in eine Datei passt. Und zur Übung drehst Du die Sortierreihenfolge um 

Das hat jetzt etwas länger gedauert, weil ich die Dateigeschichte nach Deinem letzten Post, der mir während der Vorschau aufgefallen ist, noch mit reingenommen habe.
Das Ändern einer bestehenden Highscoreliste mit Arrays musst Du allerdings selber machen, da mir das mit Arrays zu umständlich ist.

Gruß hpvw


----------



## magnet (10. Mai 2005)

Hier noch ein kleines Bsp für einfaches abspeichern deiner HighScore und auslesen aller Highscore


```
package com.fuddles.util;

import java.util.*;
import java.io.FileInputStream;
import java.io.File;
import java.io.FileOutputStream;

/**
 * Created by IntelliJ IDEA.
 * User: Hannes M
 * Date: 10.05.2005
 * Time: 20:20:28
 */
public class HighScore
{
    private Properties myScore = new Properties();

    /**
     * initialisiert Propertiedatei
     *
     * @throws Exception
     */
    public HighScore()

            throws Exception
    {
        myScore.load(new FileInputStream(System.getProperty("user.dir") + File.separator + "score.properties"));
    }
    /**
     *
     * @return SortedMap mit key = Spielername & Value=Score
     */
    public SortedMap getScoreList()
    {
        SortedMap score = new TreeMap();
        Enumeration keys = myScore.keys();
        if (keys != null)
        {
            while (keys.hasMoreElements())
            {
                String tname = keys.nextElement().toString();
                score.put(tname,myScore.getProperty(tname));
            }
            return score;
        }
        return null;
    }
    /**
     * Falls der Spieler schon in der Propertie steht und der Score größer ist als der enthaltene
     * schreibt er die höhere Score in die Datei
     * @param nickname = Spieler
     * @param score = erreichte Score
     */
    public void setnewScore(String nickname, int score)
    throws Exception
    {
        if (myScore.getProperty(nickname) != null && Integer.parseInt(myScore.getProperty(nickname).toString()) < score)
        {
            myScore.setProperty(nickname,""+score);
            myScore.store(new FileOutputStream(System.getProperty("user.dir") + File.separator + "score.properties"),"Highscore-Properties");
        }
        else if(myScore.getProperty(nickname) == null)
        {
            myScore.setProperty(nickname,""+score);
            myScore.store(new FileOutputStream(System.getProperty("user.dir") + File.separator + "score.properties"),"Highscore-Properties");
        }
    }
    /**
     * gibt alle Spieler mit der Score aus die in der Properties stehen Alphabetisch sortiert
     * @param args
     */
    public static void main(String[] args)
    {
        try
        {
            HighScore hs  =new HighScore();
            SortedMap sm = hs.getScoreList();
            Iterator ene = sm.keySet().iterator();

            while(ene.hasNext())
            {
                Object nutzer = ene.next();
                System.out.println("Spieler: "+nutzer);
                System.out.println("Score: "+sm.get(nutzer));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        /**
         * Hier noch zum abspeichern eines neuen Score
         */
        try
        {
            HighScore hs  =new HighScore();
            hs.setnewScore("Dein Name",5000);
        }
        catch (Exception e)
        {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
}
```

Packagestruktur musst du dann noch anpassen 
Die Score kommt Alphabetisch nach dem Namen sortiert
Beim 1. Aufruf wird eine Properties Datei angelegt, in dem Verzeichniss wo du das Programm startest ... viel spass 

hier noch eine Bsp Properties Datei   


```
#Highscore-Properties
#Tue May 10 20:42:55 CEST 2005
Dieter=998
Volker=999
Hans=1000
Klaus=100
Tobi=10
```


----------



## Haruka (10. Mai 2005)

hpvw hat gesagt.:
			
		

> Sicher kann ich Dir das nicht sagen, aber nach einem kurzen Überblick des Google-Suchergebnisses nach struct: Nein.


 
Ja, es ist etwas anderes. Deine beiden Sätze im vorherigen Post klangen so nen bissel nach struct, deswegen kam ich auf den falschen Schluss es sei sowas ähnliches.
Aber Danke für die Erklärung ^^


----------



## gavanaa (10. Mai 2005)

Oh man, was soll ich sagen? - Viiiieeeelen DANK!
Echt ihr seid echt die BESTEN!
Bin zwar gerade nicht am Programm dran (sitz am falschen Rechner), aber ich denke dank eurer Hilfe, dürfte ich die Highscoreliste jetz taber wirklich hinkriegen. 
Für morgen versprech ich euch ein wunderbar laufendes fertiges EinMalEins-Quiz mit Highscoreliste!

Nochmal DANKE!

DANKE!


----------



## gavanaa (19. Mai 2005)

Hallo,
So da bin ich mal wieder .
Aber leider hab ich weder das Programm abgegeben, noch das Highscoreliste richtig eingebaut. Nach einer langen Woche verzweifelten veruchens eure wunderschönen Programme in mein Quiz einzubauen bis ich nun endgültig verzweifelt gescheitert ;(.
Beschämt möchte ich euch darum bitten, mir euren Quellcode nur ein wenig zu erklären um genau zu wissen was da überhaupt gemacht wird.

Nochmals Vielen Dank!


----------



## hpvw (19. Mai 2005)

```
/*
 * Created on 10.05.2005
 *
 */

//Importieren aller benötigten Klassen

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

/**
 * @author Hans Peter von Welt
 *  
 */
public class SortArray {

    //In Objekten dieser inneren Klasse werden die einzelnen
    //Highscore-einträge (Paare aus Spieler und Punkten) abgelegt
    private class HighscoreEintrag implements Comparable {

        //Speichert den Namen
        private String name;

        //Speichert die Punkte
        private double punkte;

        //Erzeugt einen neuen HighscoreEintrag
        public HighscoreEintrag(String name, double punkte) {
            this.name = name;
            this.punkte = punkte;
        }

        /*
         * Dies ist angesprochene Vergleichsfunktion, zu der wohl hinreichend
         * genug gesagt wurde. Ggf. konkrete Fragen (Vergleich des eigenen
         * Objekts mit dem übergebenen)
         */
        public int compareTo(Object o) {
            HighscoreEintrag hE = (HighscoreEintrag) o;
            if (this.punkte > hE.getPunkte()) {
                return 1;
            } else if (this.punkte < hE.getPunkte()) {
                return -1;
            }
            return 0;
        }

        //Es folgen drei Funktionen, um die Werte auszulesen
        public String getName() {
            return name;
        }

        public double getPunkte() {
            return punkte;
        }

        public String toString() {
            return this.name + ": " + this.punkte;
        }
    }//Ende der inneren Klasse

    //Der Konstruktor, hier geht es richtig los
    public SortArray() {
        //Ein Array mit 10 einträgen vom Type HighScoreEintrag wird erstellt
        //In diesem Array werden die einzenen Paare aus Spieler und Punktestand
        //gespeichert
        HighscoreEintrag[] highscore = new HighscoreEintrag[10];

        //Ein neue "Dateiverbindung" erstellen
        File f = new File("hs.txt");

        //prüfen, ob die Datei existiert
        if (f.exists()) {
            try {
                //Wenn sie existiert werden wir sie mit dem FileReader auslesen
                FileReader fR = new FileReader(f);

                //FileReader liest ein array of char und keinen String
                char[] c = new char[(int) f.length()];

                //und in das erstellte char-array einlesen
                fR.read(c);

                //aus dem char-array einen string erzeugen, der dann den
                //Dateinhalt enthält
                String s = new String(c);

                //Den String bei Zeilenumbruch teilen und die einzelnen
                //Teile (=Zeilen) in ein array of string schreiben
                String[] entrys = s.split("\n");

                ////jede Zeile der Datei abarbeiten
                for (int i = 0; i < entrys.length; i++) {
                    //Jede einzelene Zeile bei : trennen
                    //dieser wurde als Trennzeichen zwischen Spieler und
                    //Punktestand gewählt
                    if (i < 10) {
                        String[] entry = entrys[i].split(":");

                        //einen neuen Highscoreeintrag mit den eingelesenen
                        //Erzeugen, an der entsprechenden stelle im oben
                        //defineirten Array
                        highscore[i] = new HighscoreEintrag(entry[0], Double
                                .parseDouble(entry[1]));
                    }
                }
                //den FileReader wieder schließen
                fR.close();
            } catch (FileNotFoundException e) { //falls Fehler beim
                e.printStackTrace(); //Einlesen auftreten,
            } catch (IOException e) { //diese ausgeben
                e.printStackTrace();
            }
        } else {
            //Wenn die Datei nicht existiert werden Beispieleinträge angelegt
            highscore[0] = new HighscoreEintrag("a", 10);
            highscore[1] = new HighscoreEintrag("b", 90);
            highscore[2] = new HighscoreEintrag("c", 55);
            highscore[3] = new HighscoreEintrag("d", 5);
            highscore[4] = new HighscoreEintrag("e", 20);
            highscore[5] = new HighscoreEintrag("f", 50);
            highscore[6] = new HighscoreEintrag("g", 40);
            highscore[7] = new HighscoreEintrag("h", 80);
            highscore[8] = new HighscoreEintrag("i", 30);
            highscore[9] = new HighscoreEintrag("j", 70);
        }

        //Das Array wird sortiert!
        //Dabei wird die in dem HighscoreEintrag implementierte
        //Vergleichsfunktion verwendet (ohne dass Du es merkst)
        Arrays.sort(highscore);

        //Ausgabe der Liste
        for (int i = 0; i < highscore.length; i++) {
            System.out.println(highscore[i]);
        }

        //Der FileWriter ist analog zum FileReader
        try {
            FileWriter fW = new FileWriter(f);
            for (int i = 0; i < highscore.length; i++) {
                if (i < highscore.length - 1) {
                    fW.write(highscore[i].toString() + "\n");
                } else {
                    fW.write(highscore[i].toString());
                }
            }
            fW.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //Hier geht es los
    public static void main(String[] args) {
        //Es wird zum Testen ein Objekt der Klasse SortArray erstellt
        new SortArray();
    }
}
```


----------



## sowiso (19. September 2007)

An welcher Stelle muss ich nun den Namen und die Punktzahl einsetzen?


----------

