package de.fernschulen;
//für die Klassen Arrays und Collections
import java.util.Arrays;
import java.util.Collections;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.util.Duration;
public class MemoryFeld {
//eine innere Klasse für den Eventhandler des Timer
class TimerHandler implements EventHandler<ActionEvent> {
@Override
//die Methode ruft die Methode karteSchliessen() auf
public void handle(ActionEvent arg0) {
karteSchliessen();
}
}
//***************************************Aufgabe1***************************************
class TimerProgrammAus implements EventHandler<ActionEvent> {
@Override
//die Methode beendet das Programm
public void handle(ActionEvent arg0) {
Platform.exit();
}
}
//***************************************Aufgabe1***************************************
//***************************************Aufgabe3***************************************
class TimerSchummelnAus implements EventHandler<ActionEvent> {
@Override
//
//die Methode
public void handle(ActionEvent arg0) {
//
for (int i = 0; i <= 41; i++) {
if (karten[i].isNochImSpiel() == true) {
karten[i].rueckseiteZeigen(false);
//karten[i + 1].rueckseiteZeigen(false);
i++;
}
}
System.out.println("Die Karten wurden rückgesetzt");
}
}
//***************************************Aufgabe3***************************************
//das Array für die Karten
private MemoryKarte[] karten;
//das Array für die Namen der Grafiken
private String[] bilder = {"grafiken/apfel.jpg", "grafiken/birne.jpg", "grafiken/blume.jpg", "grafiken/blume2.jpg",
"grafiken/ente.jpg", "grafiken/fisch.jpg", "grafiken/fuchs.jpg", "grafiken/igel.jpg",
"grafiken/kaenguruh.jpg", "grafiken/katze.jpg", "grafiken/kuh.jpg", "grafiken/maus1.jpg",
"grafiken/maus2.jpg", "grafiken/maus3.jpg", "grafiken/melone.jpg", "grafiken/pilz.jpg",
"grafiken/ronny.jpg", "grafiken/schmetterling.jpg","grafiken/sonne.jpg",
"grafiken/wolke.jpg", "grafiken/maus4.jpg"};
//für die Punkte
private int menschPunkte, computerPunkte;
//zwei Labels für die Punkte einen für den Sieger(Aufgabe 1) und eins für den aktuellen Spieler(Aufgabe 2)
private Label menschPunkteLabel, computerPunkteLabel, sieger, aktuellerSpieler;
//***************************************Aufgabe3***************************************
//einen Button für die Schummelfunktion
private Button schummeln;
//***************************************Aufgabe3***************************************
//wie viele Karten sind aktuell umgedreht?
private int umgedrehteKarten;
//für das aktuell umdrehte Paar
private MemoryKarte[] paar;
//für den aktuellen Spieler
private int spieler;
//das "Gedächtnis" für den Computer
//er speichert hier wo das Gegenstück liegt
private int[][] gemerkteKarten;
//für die Spielstärke
private int spielstaerke;
//für den Timer
private Timeline timer;
//der Konstruktor
public MemoryFeld() {
//das Array für die Karten erstellen, insgesamt 42 Stück
karten = new MemoryKarte[42];
//für das Paar
paar = new MemoryKarte[2];
//für das Gedächtnis
//es speichert für jede Karte paarweise die Position im Spielfeld
gemerkteKarten = new int[2][21];
//keiner hat zu Beginn einen Punkt
menschPunkte = 0;
computerPunkte = 0;
//es ist keine Karte umgedreht
umgedrehteKarten = 0;
//der Mensch fängt an
spieler = 0;
//die Spielstärke ist 10
spielstaerke = 0;
//es gibt keine gemerkten Karten
for (int aussen = 0; aussen < 2; aussen++)
for (int innen = 0; innen < 21; innen++)
gemerkteKarten[aussen][innen] = -1;
}
//die Methode erstellt die Oberfläche und zeichnet die Karten über eine eigene Methode
//übergeben wird ein FlowPane
public FlowPane initGUI(FlowPane feld) {
//für die Ausgaben
kartenZeichnen(feld);
menschPunkteLabel = new Label();
computerPunkteLabel = new Label();
menschPunkteLabel.setText(Integer.toString(menschPunkte));
computerPunkteLabel.setText(Integer.toString(computerPunkte));
//***************************************Aufgabe3***************************************
schummeln = new Button();
schummeln.setText("schummeln");
//***************************************Aufgabe3***************************************
//***************************************Aufgabe2***************************************
aktuellerSpieler = new Label();
aktuellerSpieler.setText("Der Mensch");
//***************************************Aufgabe2***************************************
//***************************************Aufgabe1***************************************
sieger = new Label();
sieger.setText("");
//***************************************Aufgabe1***************************************
//in zwei Spalten anzeigen
GridPane tempGrid = new GridPane();
//und einfügen, dabei werden die Koordinaten angegeben
tempGrid.add(new Label("Mensch: "), 0 , 0 );
tempGrid.add(menschPunkteLabel, 1, 0);
tempGrid.add(new Label("Computer: "), 0, 1);
tempGrid.add(computerPunkteLabel, 1 ,1);
//***************************************Aufgabe2***************************************
tempGrid.add(new Label("Es Zieht: "), 0, 2);
tempGrid.add(aktuellerSpieler, 1, 2);
//***************************************Aufgabe2***************************************
//***************************************Aufgabe1***************************************
tempGrid.add(new Label("Sieger: "), 0, 3);
tempGrid.add(sieger, 1 ,3);
//***************************************Aufgabe1***************************************
//***************************************Aufgabe3***************************************
tempGrid.add(schummeln, 1, 4);
//***************************************Aufgabe3***************************************
feld.getChildren().add(tempGrid);
return feld;
}
//das eigentliche Spielfeld erstellen
private void kartenZeichnen(FlowPane feld) {
int count = 0;
for (int i = 0; i <= 41; i++) {
//eine neue Karte erzeugen
karten[i] = new MemoryKarte(bilder[count], count, this);
//bei jeder zweiten Karte kommt auch ein neues Bild
if ((i + 1) % 2 == 0)
count++;
}
//die Karten werden gemischt
Collections.shuffle(Arrays.asList(karten));
//und ins Spielfeld gesetzt
for (int i = 0; i <= 41; i++) {
feld.getChildren().add(karten[i]);
//die Position der Karte setzen
karten[i].setBildPos(i);
}
}
//die Methode übernimmt die wesentliche Steuerung des Spiels
//Sie wird beim Anklicken einer Karte ausgeführt
public void karteOeffnen(MemoryKarte karte) {
//***************************************Aufgabe3***************************************
// Aktion hinzufügen
schummeln.setOnAction(event -> {
schummelfunktion();
//System.out.println("Button wurde geklickt!");
});
//***************************************Aufgabe3***************************************
//zum Zwischenspeichern der ID und der Position
int kartenID, kartenPos;
//die Karten zwischenspeichern
paar[umgedrehteKarten]=karte;
//die ID und die Position beschaffen
kartenID = karte.getBildID();
kartenPos = karte.getBildPos();
//die Karte in das Gedächtnis des Computers eintragen
//aber nur dann, wenn es noch keinen Eintrag an der entsprechenden Stelle gibt
if ((gemerkteKarten[0][kartenID] == -1))
gemerkteKarten[0][kartenID] = kartenPos;
else
//wenn es schon einen Eintrag gibt
//und der nicht mit der aktuellen Position übereinstimmt, dann haben wir die
//zweite Karte gefunden
//die wird dann in die zweite Dimension eingetragen
if (gemerkteKarten[0][kartenID] != kartenPos)
gemerkteKarten[1][kartenID] = kartenPos;
//umgedrehte Karten erhöhen
umgedrehteKarten++;
//sind zwei Karten umgedreht worden?
if (umgedrehteKarten == 2) {
//dann prüfen wir, ob es ein Paar ist
paarPruefen(kartenID);
//den Timer erzeugen
timer = new Timeline(new KeyFrame(Duration.millis(2000), new TimerHandler()));
//und starten
timer.play();
}
//haben wir zusammen 21 Paare, dann ist das Spiel vorbei
if (computerPunkte + menschPunkte == 21) {
abschlussDialog();
}
}
//die Methode dreht die Karten wieder auf die Rückseite
//bzw. nimmt sie aus dem Spiel
private void karteSchliessen() {
boolean raus = false;
//ist es ein Paar?
if (paar[0].getBildID() == paar[1].getBildID())
raus = true;
//wenn es ein Paar war, nehmen wir die Karten aus dem Spiel
//sonst drehen wir sie nur wieder um
paar[0].rueckseiteZeigen(raus);
paar[1].rueckseiteZeigen(raus);
//es ist keine Karte mehr geöffnet
umgedrehteKarten = 0;
//hat der Spieler kein Paar gefunden?
if (raus == false)
//dann wird der Spieler gewechselt
spielerWechseln();
else
//hat der Computer ein Paar gefunden?
//dann ist er noch einmal an der Reihe
if (spieler == 1)
computerZug();
}
//die Methode prüft, ob ein Paar gefunden wurde
private void paarPruefen(int kartenID) {
if (paar[0].getBildID() == paar[1].getBildID()) {
//die Punkte setzen
paarGefunden();
//die Karten aus dem Gedächtnis löschen
gemerkteKarten[0][kartenID]=-2;
gemerkteKarten[1][kartenID]=-2;
}
}
//die Methode setzt die Punkte, wenn ein Paar gefunden wurde
private void paarGefunden() {
//spielt gerade der Mensch?
if (spieler == 0) {
menschPunkte++;
menschPunkteLabel.setText(Integer.toString(menschPunkte));
}
else {
computerPunkte++;
computerPunkteLabel.setText(Integer.toString(computerPunkte));
}
}
//die Methode wechselt den Spieler
private void spielerWechseln() {
//wenn der Mensch an der Reihe war,
//kommt jetzt der Computer
if (spieler == 0) {
spieler = 1;
computerZug();
}
else
spieler = 0;
//***************************************Aufgabe2***************************************
//Prüfen ob der Menschliche Spieler dran ist und im Label ausgeben.
if (spieler == 0) {
aktuellerSpieler.setText("Der Mensch");
//***************************************Aufgabe3***************************************
// schummelfunktion();
//***************************************Aufgabe3***************************************
}
else
//Prüfen ob der Computer dran ist und im Label ausgeben.
if (spieler == 1)
aktuellerSpieler.setText("Der Computer");
//***************************************Aufgabe2***************************************
}
//die Methode setzt die Computerzüge um
private void computerZug() {
int kartenZaehler = 0;
int zufall = 0;
boolean treffer = false;
//zur Steuerung über die Spielstärke
if ((int)(Math.random() * spielstaerke) == 0) {
//erst einmal nach einem Paar suchen
//dazu durchsuchen wir das Array gemerkteKarten, bis wir in beiden Dimensionen
//einen Wert finden
while ((kartenZaehler < 21) && (treffer == false)) {
//gibt es in beiden Dimensionen einen Wert größer oder gleich 0?
if ((gemerkteKarten[0][kartenZaehler] >=0) && (gemerkteKarten[1][kartenZaehler] >=0)) {
//dann haben wir ein Paar
treffer = true;
//die Vorderseite der Karte zeigen
karten[gemerkteKarten[0][kartenZaehler]].vorderseiteZeigen();
//und dann die Karte öffnen
karteOeffnen(karten[gemerkteKarten[0][kartenZaehler]]);
//die zweite Karte auch
karten[gemerkteKarten[1][kartenZaehler]].vorderseiteZeigen();
karteOeffnen(karten[gemerkteKarten[1][kartenZaehler]]);
}
kartenZaehler++;
}
}
//wenn wir kein Paar gefunden haben, drehen wir zufällig zwei Karten um
if (treffer == false) {
//solange eine Zufallszahl suchen, bis eine Karte gefunden wird, die noch im Spiel ist
do {
zufall = (int)(Math.random() * karten.length);
} while (karten[zufall].isNochImSpiel() == false);
//die erste Karte umdrehen
//die Vorderseite der Karte zeigen
karten[zufall].vorderseiteZeigen();
//und dann die Karte öffnen
karteOeffnen(karten[zufall]);
//für die zweite Karte müssen wir außerdem prüfen, ob sie nicht gerade angezeigt wird
do {
zufall = (int)(Math.random() * karten.length);
} while ((karten[zufall].isNochImSpiel() == false) || (karten[zufall].isUmgedreht() == true));
//und die zweite Karte umdrehen
karten[zufall].vorderseiteZeigen();
karteOeffnen(karten[zufall]);
}
}
//die Methode liefert, ob Züge des Menschen erlaubt sind
//die Rückgabe ist false, wenn gerade der Computer zieht
//oder wenn schon zwei Karten umgedreht sind
//sonst ist die Rückgabe true
public boolean zugErlaubt() {
boolean erlaubt = true;
//zieht der Computer?
if (spieler == 1)
erlaubt = false;
//sind schon zwei Karten umdreht?
if (umgedrehteKarten == 2)
erlaubt = false;
return erlaubt;
}
//***************************************Aufgabe1***************************************
//die Methode zeigt den Sieger des Memoryspiels an und beendet das Programm.
private void abschlussDialog() {
//Variable vereinbaren für die Anzeige des Siegers
String sieger, headerDialog;
//prüfen ob der Mensch mehr Punkte hat.
//Falls ja hat er gewonnen und wenn nicht hat der Computer gewonnen.
if (menschPunkte > computerPunkte) {
this.sieger.setText("Der Mensch hat gewonnen");
sieger = "Mensch";
headerDialog = "Herzlichen Glückwunsch!";
}
else {
this.sieger.setText("Der Computer hat gewonnen");
sieger = "Computer";
headerDialog = "Arbeite noch etwas an deinem Gedächtnis...";
}
//den Dialog erzeugen
Alert meinDialog = new Alert(AlertType.INFORMATION,"Der " + sieger + " hat gesiegt!");
//den Text setzen
meinDialog.setHeaderText(headerDialog);
//den Titel setzen
meinDialog.setTitle("Gewinner");
//den Dialog anzeigen
meinDialog.showAndWait();
//den Timer erzeugen um das Ende für 5 Sekunden hinaus zuzögern.
timer = new Timeline(new KeyFrame(Duration.millis(5000), new TimerProgrammAus()));
//und starten
timer.play();
}
//***************************************Aufgabe1***************************************
//***************************************Aufgabe3***************************************
//die Methode setzt die Schummelfunktion um.
//
//
private void schummelfunktion() {
//sicherstellen dass nur beim Menschenzug gedrückt werden darf
if (spieler == 0) {
//alle Karten auf dem Spielfeld aufdecken
for (int i = 0; i <= 41; i++) {
if (karten[i].isNochImSpiel() == true) {
karten[i].vorderseiteZeigen();
System.out.println("Karte " + i + " ist noch im Spiel");
//karten[i + 1].vorderseiteZeigen();
//System.out.println("Karte " + (i + 1) + " ist noch im Spiel"); i++;
}
}
//den Timer erzeugen um die Karten nach 3 Sekunden umzudrehen.
timer = new Timeline(new KeyFrame(Duration.millis(3000), new TimerSchummelnAus()));
//und starten
timer.play();
}
}
//***************************************Aufgabe3***************************************
}