Vokabeltrainer

bene98

Aktives Mitglied
Guten Tag,
Nachdem ich nun einen ersten Taschenrechner mit GUI programmiert habe und es mir Spaß gemacht hat , würde ich gerne dabei bleiben und mich über kleine Projekt versuchen etwas Programmiererfahrung zu bekommen.
Als nächstes würde ich gerne einen kleinen Vokabeltrainer machen. Es soll zwei Textfelder geben. Eines für die deutsche Bedeutung und eins für die englische Entsprechung.
Es soll ein kleine Spiel sein. Man hat z.B. fünf Fehlversuche. Über ein Zufallsgenerator wird ein Wort ausgewählt und in einem der Textfelder angezeigt. Der Anwender gibt die Bedeutung in der jeweils anderen Sprache ein (Der Einfachheit halber werde ich nur eine Bedeutung pro Wort eintragen.
Anschließend gibt es einen Vergleich des eingetragenen Strings mit der gespeicherten Bedeutung.
Es soll gezählt werden, wie viele Wörpaare man insgesamt absolviert hat (Highscore).

Meine Hauptfrage vor Beginn.
Wie soll ich die Wortpaare abspeichern?
Zunächst habe ich an eine Array_List gedacht. Diese müsste mindestens 2Dimensionen haben (D, EN).
Die Schwierigkeit sehe ich in dem Einsatz des Zufallsgenerators. Oder kann man da was mit dem Index des Arrays machen (Dass er einen zufälligen Indexert aufruft.) Oder wäre eine dreidimensionale Array-Liste mit eine Dimension, die eine Zahl trägt sinnvoll?

Andernfalls habe ich noch an eine Hash_Tabelle gedacht. Ich weeiß aber nicht, ob die Eingaben dann so einfach abzugleichen sind (Könnte man dann auch String-Methoden einsetzen?

Danke
 

Javinner

Top Contributor
Wie soll ich die Wortpaare abspeichern?
Ich würde dafür eine Klasse ins Leben rufen, welche drei Attributen besitzt:
  • String deutschesWort
  • String englischesWort
  • boolean sprachenWechsel
Die Schwierigkeit sehe ich in dem Einsatz des Zufallsgenerators
Du könntest ein Wort aus dem Array nehmen und dieses Wort aus dem Array entfernen, so dass es nicht mehr vorkommt. Das machst du solange, bis das Array gegen Null läuft, so dass du es in dem Fall wieder einlädst.
Oder wäre eine dreidimensionale Array-Liste mit eine Dimension, die eine Zahl trägt sinnvoll?
Ein Dreidimensionales Array ist etwas, was ich mir immer gerne spare :D Da gibt es wesentlich besser verständliche Strukturen.
 

mihe7

Top Contributor
Erstmal ist es sehr gut, dass Du Dir im Voraus Gedanken machst und nicht blind darauf los programmierst.

Es soll ein kleine Spiel sein. Man hat z.B. fünf Fehlversuche. Über ein Zufallsgenerator wird ein Wort ausgewählt und in einem der Textfelder angezeigt. Der Anwender gibt die Bedeutung in der jeweils anderen Sprache ein (Der Einfachheit halber werde ich nur eine Bedeutung pro Wort eintragen.
Anschließend gibt es einen Vergleich des eingetragenen Strings mit der gespeicherten Bedeutung.
Es soll gezählt werden, wie viele Wörpaare man insgesamt absolviert hat (Highscore).

Mit einer solchen Beschreibung hast Du schon halb gewonnen. Ich zeige Dir mal, wie man so etwas lösen kann.

Zunächst kannst Du Dich auf den Kern des Spiels konzentrieren, insbesondere die GUI und die Highscore unberücksichtigt lassen, denn ob Du nun den Spaß grafisch anzeigst oder Spielstände über mehrere Spiele hinweg verwaltest, hat keinen Einfluss auf den Spielablauf.

Als erstes schaust Du Dir die Beschreibung im Detail an und versuchst, Informationen daraus zu gewinnen. Dabei hilft es, zu abstrahieren. Ob ein Wort nun per Zufallsgenerator ausgewählt wid oder Wörter in Textfelder angezeigt werden, sind Details. Das "große Ganze" besteht aus dem Rest der Geschichte: das Spiel wählt ein Wort. Der Spieler versucht, das Wort "zu lösen". Her er dies nicht geschafft, zählt dies als Fehlversuch. Sobald er eine bestimmte Anzahl an Fehlversuchen erreicht hat, ist das Spiel beendet. Hat der Spieler dagegen die richtige Lösung angegeben, gibt dies einen "Punkt" und der Spaß beginnt von vorne.

Nach "außen" bekannt sein muss folglich nur:

- das aktuell gewählte Wort
- die Zahl der verbleibenden Fehlversuche
- die Zahl der bereits richtig gelösten Wörter

Es gibt auch nur zwei Aktionen:

- starte neues Spiel
- gib Lösung zum aktuellen Wort an

Unabhängig von der konkreten Implementierung kann man die Schnittstelle des Spiels bereits angeben:

Java:
interface Vokabelspiel {
    String aktuellesWort();
    int verbleibendeVersuche();
    int anzahlPunkte();

    void neuesSpiel();
    void versucheLoesung(String wort);
}

Insbesondere spielt es erstmal gar keine Rolle, wie das intern gespeichert wird, oder ob zu einem Wort mehrere Lösungen zugelassen sind.

Wie sieht nun eine mögliche Implementierung aus? Tatsächlich gibt es mehrere Möglichkeiten, die Wortmengen zu verwalten. Im konkreten Fall bietet sich eine Klasse an, die zu einem Wort die Übersetzungen kennt.

Java:
public class StandardVokabelspiel implements Vokabelspiel {
    static class Wort {
        String wort;
        Set<String> uebersetzungen;
    }

    private final List<Wort> wortliste;

    // ...
}

Das mal als Anstubser von meiner Seite.
 

bene98

Aktives Mitglied
Ich glaub ich muss ein bisschen einfacher anfangen. Ich bin noch ziemlicher Anfänger.
Ich wuerde erstmal auf den Zufallsgenerator verzichten, weil es die Komplexität zu stark erhöht.
Entschuldigung dafür, dass ich die Vorschläge nicht schneller umsetzen kann. Dafür fehlt es wohl noch an Vorwissen/Erfahrungen.

1. Ich hätte eine Klasse Vokabelspiel,
2. Ich hätte die Attribute: aktuellesWort, anzahlPunkte, verbleibendeVersuche.
3. Ich hätte als Objekte die Vokabelliste mit ihren Wortpaaren.
4. Ich hätte als Methoden: a neues Spiel (setzt die Anzahl Punkte auf 0, verbleibendeVersuche auf 5, sucht ein Wort aus der Liste und zeigt es an); b versucheLoesung (gleicht die Lösung ab, solange noch verbleibende Versuche offen sind. Bei einer richtigen Lösung gibt sie "richtig" aus. Die Anzahl der Punkte wird erhöht.Bei einer falschen Lösung wird die Anzahl der verbleibenden Versuche gemindert.
5. Ich hätte später noch einiges für die graphische Darstellung, aber dies ist zunächst nicht wichtig.

Danke
 

mihe7

Top Contributor
Ich wuerde erstmal auf den Zufallsgenerator verzichten, weil es die Komplexität zu stark erhöht.
Im ersten Schritt auf Dinge zu verzichten, ist eine gute Idee.

Und auch der Rest sieht soweit schon einmal sehr gut aus. Ein Punkt wäre noch zu "bemängeln":
Bei einer richtigen Lösung gibt sie "richtig" aus.
Das Spiel selbst gibt gar nichts aus. Die Ausgabe ist Aufgabe eines anderen Programmteils. Ob der nun "richtig" auf den Bildschirm schreibt, einen Tusch spielt oder was auch immer macht, interessiert das Spiel nicht. Was das Spiel machen könnte: es kann zurückgeben, ob die Antwort richtig war, z. B. mit einem boolean, dann ändert sich die Methode zu
Java:
boolean versucheLoesung(String wort);

Ich brauche wahrscheinlich eine weitere Methode (neuesWort), die ein aktuelles Wort einsetzt.
Das würde in versucheLoesung() geschehen: wenn die Lösung richtig war, gibt es ein neues aktuelles Wort.

An dem Beispiel sieht man deutlich den Unterschied zwischen einer prozeduralen und einer objektorientierten Herangehensweise. Es gibt die Spielregel, dass ein neues Wort gewählt wird, wenn eine richtige Lösung angegeben wurde.

Beim prozeduralen Ansatz gewinnt der Aufrufer Informationen aus einem Objekt und trifft anhand dieser Entscheidungen. Dadurch verlagert sich die Spiellogik (Umsetzung der Spielregel) in Richtung des Aufrufers:

Java:
if (spiel.versucheLoesung(wort)) { // frage das Spiel, ob die Lösung richtig war,
    spiel.naechstesWort();  // wenn die Lösung richtig war, wähle nächstes Wort
}
Die Spielregel ist also außerhalb der Kontrolle des Spiels. Setzt Du die Regel dagegen in versucheLoesung() um, hat der Aufrufer gar keine Möglichkeit, einfach (k)ein nächstes Wort zu wählen.
 
Ich würde an deiner Stelle erstmal ein Klassendiagramm erstellen(uml), damit du die Übersicht nicht verlierst.

Nach deiner Beschreibung würde ich mit den Klassen Vokabel(mit englischer bedeutung und deutscher bedeutung)

Und Vokabelsammlung(arraylist<Vokabel>)

Wenn du dann noch sinnvolle Methoden schreibst, kannst du später von deiner vokabelspiel aus einfach eine Sammlung erstellen mit vokabeln. Das dürfte das ganze vereinfachen.

PS: sorry wenn du schon soweit warst, aus deinem ersten Post konnte ich das nicht erkennen.

PSS:

Ich würde gui erstmal hintenanstellen und gucken, dass das ganze auf der konsole funktioniert(also dir wird ein Wort angezeigt, du gibst übersetzung ein. Richtig=>neues Wort, falsch=>Anzahl restversuche anzeigen).
 

bene98

Aktives Mitglied
@Keeperofnature
wenn ich es richtig verstanden habe, dann schlägst du eine weitere Klasse vor, in der die Vokabelliste in Form einer Arraylist vorliegt.
Was ich nich verstehe ist, weshalb diese zweite Klasse eine Vereinfachung bringt.
Was die Sache mit der GUi angeht, werde ich es genau so machen, wie Du vorschlägst.
Danke
 
Das ganze macht deine höheren Funktionen weniger komplex. Wenn du die arraylist und alles was du auf ihr ausführen willst(getLoesung() getRandomVokabel() oder andere) in einer anderen Klasse hast, brauchst du das nicht in deine Main schreiben.
Das ist nicht notwendig, aber ich finde es sinnvoll.
 

bene98

Aktives Mitglied
Folgende Anfängerfrage: Ich habe den Eindruck, dass ich die Methoden nicht aufgerufen werden.
Der gibt nur aus: Ich bin mit meinem Latein am Ende:)
Liegt dies an einer falsch gesetzten geschweiften Klammer?
Java:
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Vokabel {
int verbleibendeVersuche = 5;
int anzahlPunkte;
String aktuellesWort;

public Vokabel() { System.out.println("Vokabelspiel - Ich bin mit meinem Latein am Ende!");} 

public void neuesSpiel() {
System.out.println("Ein neues Spiel beginnt");     
}

public void versucheLoesung() {
aktuellesWort = "Tischtennis";     
Scanner scanner = new Scanner(System.in);
String worteingabe = scanner.next();
System.out.println("Bitte das Wort eingeben");
if (worteingabe.equals(aktuellesWort)) { System.out.println("Super. Dies ist die richtige Lösung!");} else{System.out.println("falsche Eingabe");}
anzahlPunkte ++;
scanner.close();}



    public static void main (String[] args){
    Vokabel Vokabelspiel = new Vokabel(); }}
 

mihe7

Top Contributor
Ich habe den Eindruck, dass ich die Methoden nicht aufgerufen werden
Ja.
Liegt dies an einer falsch gesetzten geschweiften Klammer?
Nein, das liegt daran, dass Du keine Methoden aufrufst.

Ich glaube, Du meinst, dass die Methoden in der Reihenfolge aufgerufen werden, wie sie in der Datei stehen. Das ist nicht der Fall. Es handelt sich hier einfach um Definitionen. In welcher Reihenfolge die erfolgen, ist egal.

In main erzeugst Du ein Objekt (bitte Variablennamen in lowerCamelCase) und jetzt kannst Du Methoden dieses Objekts aufrufen:
Java:
    public static void main (String[] args){
        Vokabel vokabelspiel = new Vokabel();  // erstmal ein Objekt erzeugen
        vokabelspiel.neuesSpiel();  // und dann dem Objekt sagen, dass es ein neues Spiel starten soll
    }
 

bene98

Aktives Mitglied
Hi, ich habe jetzt zum Test ein zweidimensionales Array produziert. ich bräuchte aber wohl eine Getter-Methode, um damit weiter arbeiten zu können. Oder gibt es ne bessere Möglichkeit?
Java:
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Vokabel {
int verbleibendeVersuche = 5;
int anzahlPunkte;
String aktuellesWort;

public Vokabel() { System.out.println("Vokabelspiel - Ich bin mit meinem Latein am Ende:-)!");}


public void neuesSpiel (){
aktuellesWort= "Tischtennnis";
System.out.println("Ein neues Spiel beginnt");  
}

public void versucheLoesung() {
Scanner scanner = new Scanner(System.in);
System.out.println("Bitte das Wort eingeben");
String worteingabe = scanner.next();

if (worteingabe.equals(aktuellesWort)) { System.out.println("Super. Dies ist die richtige Lösung!"); anzahlPunkte ++;
} else{System.out.println("falsche Eingabe"); verbleibendeVersuche--; System.out.println("Du hast noch " + verbleibendeVersuche + " Leben"); }
scanner.close();}
 

bene98

Aktives Mitglied
Java:
public class Vokabellist {
public static void main (String[] args) {   
String [][] Vokabelliste = new String [2][2];
Vokabelliste [0][0] = "Buch";
Vokabelliste [0][1] = "book";
Vokabelliste [1][0] = "Handy";
Vokabelliste [1][1] = "mobile";

System.out.println(Vokabelliste[0][1]);
}

public String[][] getVokabelliste[][]() {
return Vokabelliste[][];
}}
 

bene98

Aktives Mitglied
Könnte mir bitte jemand weiterhelfem- Ich kann zwar die Elemente des Arrays direkt über Sysout ausgeben, aber ich müsste dies ja aus meinen anderen Merhoden wie neues Spiel() machen können.
Wäre eine Getter-methode hier richtig? was mache ich damit falsch?
 

Javinner

Top Contributor
Ich glaub ich muss ein bisschen einfacher anfangen
Was sehr hilfreich wäre, ist das Grundwissen über die Strukturen, die dir Java bietet. Du willst unbedingt ein Array?! Nimm eine ArrayList, welche vom Interface List erbt und intern mit einem Array arbeitet.

Bevor du dich ans Programmieren machst, solltest du ein Ablaufplan entwickeln, was passieren soll, nach dem du dein Programm gestartet hast.
  • Startmenü: was ist alles sichtbar, was kann ich alles machen?
  • Vorhandene Session üben?
  • Neue erstellen?
  • ...
Das Grafische würde ich an deiner Stelle erstmal lassen und das Ganze in der Konsole der IDE laufen lassen. Lerne erstmal einiges über Klassen, Vererbung, Abhängigkeiten usw., bevor du dich an GUI ranmachst.
 

bene98

Aktives Mitglied
Guten Abend,
Ich hab die Sache jetzt mal für die Konsole gemacht. Mit einer zweidimensionalen ArrayList ging es weiter.
Ich denke mal die größte Schwierigkeit für mich liegt darin, die Mehode naechstes Wort in neues Wort zu integrieren und mit einer while Schleife so lange laufen zu lassen wie der currentIndex<anzahlVokabeln ist.
Außerdem kann ich weiter nicht von außerhalb der Methode neuesSpiel auf die Indizes der verschieden ArrayLists zugreifen. Deswegen muss ich die immer wieder in der Main-Methode aufrufen - was natürlich nicht ganz so sinnvoll ist.

Java:
import java.util.*;
import java.util.List;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Vokabel {
int verbleibendeVersuche = 5;
int anzahlPunkte;
String anfangswort;
String aktuellesWort;
String englischeUbersetzung;
String englischeUbersetzungzwo;
int currentIndex=0;
int anzahlVokabeln;

public Vokabel() { System.out.println("Vokabelspiel - Ich bin mit meinem Latein am Ende:-)!");
} 
public void neuesSpiel (){
    
ArrayList <ArrayList<String>> Vokabelliste = new ArrayList <ArrayList<String>>();
ArrayList[] Zeilen = new ArrayList[2];
Zeilen[0] = new ArrayList();
Zeilen[1] = new ArrayList();
Vokabelliste.add(Zeilen[0]);
Vokabelliste.add(Zeilen[1]);
Zeilen[0].add("Hummer");
Zeilen[0].add("Hemd");
Zeilen[0].add("Kinn");
Zeilen[0].add("Wange");
Zeilen[0].add("Wimper");
Zeilen[0].add("Heizkörper");

Zeilen[1].add("lobster");
Zeilen[1].add("shirt");
Zeilen[1].add("chin");
Zeilen[1].add("cheek");
Zeilen[1].add("lash");
Zeilen[1].add("radiator");

anzahlVokabeln=Zeilen[0].size();

anfangswort= (String) Zeilen[0].get(0);
englischeUbersetzung= (String) Zeilen[1].get(0);
aktuellesWort=(String) Zeilen[0].get(currentIndex);
englischeUbersetzungzwo= (String) Zeilen[1].get(currentIndex);
currentIndex++;
}


public void neuesWort() {       
Scanner scanner = new Scanner(System.in);
System.out.println("Bitte die englische Übersetzung des folgenden Wortes eingeben:" + anfangswort);
String worteingabe = scanner.next();
if (worteingabe.equals(englischeUbersetzung)) { System.out.println("Super. Dies ist die richtige Lösung!"); anzahlPunkte ++;
} else{System.out.println("falsche Eingabe"); verbleibendeVersuche--; System.out.println("Du hast noch " + verbleibendeVersuche + " Leben");
}}


public void naechstesWort() {
System.out.println("Bitte die englische Übersetzung des folgenden Wortes eingeben:" + aktuellesWort);
Scanner scannerzwo = new Scanner(System.in);   
String worteingabezwo = scannerzwo.next();
if (worteingabezwo.equals(englischeUbersetzungzwo)) { System.out.println("Super. Dies ist die richtige Lösung!"); anzahlPunkte ++;
} else{System.out.println("falsche Eingabe"); verbleibendeVersuche--; System.out.println("Du hast noch " + verbleibendeVersuche + " Leben"); }
;}




    public static void main (String[] args){
    Vokabel Vokabelspiel = new Vokabel();
    Vokabelspiel.neuesSpiel();
    Vokabelspiel.neuesWort();
    Vokabelspiel.neuesSpiel();
    Vokabelspiel.naechstesWort();
    Vokabelspiel.neuesSpiel();
    Vokabelspiel.naechstesWort();
    Vokabelspiel.neuesSpiel();
    Vokabelspiel.naechstesWort();
    Vokabelspiel.naechstesWort();
    Vokabelspiel.neuesSpiel();
    Vokabelspiel.naechstesWort();
    Vokabelspiel.neuesSpiel();
    Vokabelspiel.naechstesWort();
    }
    }
 

Javinner

Top Contributor
Java:
public class VokabelTrainerDemo
{

 
    public static void main(String[] args)
    {
        List<Wort> woerter = new ArrayList<>();
        woerter.add(new Wort("Brot", "Bread"));
        woerter.add(new Wort("Biene", "Bee"));
        woerter.add(new Wort("Vogel", "Bird"));
        woerter.add(new Wort("Messer", "Knife"));
        VokabelWortSammlung sammlung = new VokabelWortSammlung("Meine Sammlung", woerter);
        Scanner scanner = new Scanner(System.in);
        int richtig = 0;
        int falsch = 0;
        String antwort;
        String ende = "ENDE";
        boolean imSpiel = false;
        while(!imSpiel)
        {
            System.out.println(sammlung.aktuellesWort().getDeutsch());
            antwort = scanner.nextLine();
            if(antwort.equalsIgnoreCase(sammlung.aktuellesWort().getEnglisch()))
            {
                richtig++;
            } else
            {
                falsch++;
            }
            sammlung.aktualisiereWort();
            System.out.println("Weiter?");
            imSpiel = scanner.nextLine().equalsIgnoreCase(ende);
        }
        System.out.println("Richtig erraten: " + richtig + ", falsche Antworten: " + falsch);
       
    }
   
}
public class VokabelWortSammlung
{

    private final String sammlungName;
    private final List<Wort> woerter;
    private Wort aktuellesWort;

    public VokabelWortSammlung(String sammlungName, List<Wort> woerter)
    {
        this.sammlungName = sammlungName;
        this.woerter = woerter;
        this.aktuellesWort = woerter.get(0);
    }

    public int laengeSammlung()
    {
        return this.woerter.size();
    }

    public Wort aktuellesWort()
    {
        return this.aktuellesWort;
    }

    public String getSammlungName()
    {
        return sammlungName;
    }

    public void aktualisiereWort()
    {
        int index = this.woerter.indexOf(this.aktuellesWort);
        index++;
        this.aktuellesWort = index < this.laengeSammlung() ? this.woerter.get(index) : this.woerter.get(0);
    }

}

public class Wort
{

    private final String deutsch;
    private final String englisch;

    public Wort(String deutsch, String englisch)
    {
        this.deutsch = deutsch;
        this.englisch = englisch;
    }

    public String getDeutsch()
    {
        return deutsch;
    }

    public String getEnglisch()
    {
        return englisch;
    }

}
 

Ähnliche Java Themen

Neue Themen


Oben