/**
  *
  * Programmieraufgabe P-14 (Spiel Nim, nim.jar)
  *
  * @author Leonhard Fellermayr
  * @version 1.0
  *
  */

/** Benštigte Packages: zum Einlesen von der Konsole, sowie fŸr den Zufallsgenerator. */

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Random;

/** Implementierung der Klasse Spiel. */

public class Spiel {

	/** ***** VARIABLEN ***** */

	/**
	  *  @param console Instanz von BufferedReader zum Einlesen von der Konsole
	  *  @param gen Instanz des Random Generators zur Erzeugung von Zufallszahlen
	  *  @param nr_zug Dieser ZŠhler numeriert die einzelnen SpielzŸge
	  *
	  */

        private static BufferedReader console = new BufferedReader (new InputStreamReader (System.in));

	public static Random gen = new Random ();

	private static int nr_zug = 1;


	/** ***** PRIVATE METHODEN ***** */

	/**
	  *  benutzerZug () - Realisiere einen vollstŠndigen Zug des Spielers vor dem Computer.
	  *  Frage dabei die Anzahl der zu entfernenden Steine ab und ŸberprŸfe den RŸckgabewert
	  *  von Haufen.entferneSteine () auf mšgliche Fehlercodes. Ggf. Wiederholung der
	  *  Eingabeaufforderung durch rekursiven Aufruf.
	  *
	  *  @return void
	  *
	  */

	private static void benutzerZug () throws IOException {

		System.out.print ("Dein Zug   : ");

		/** Integer-Rueckgabewert von Haufen.entferneSteine () in result */

		int result = Haufen.entferneSteine (Integer.parseInt (console.readLine()));

		if (result == Haufen.ERR_TOO_MANY)
			System.out.print ("FEHLER     : Du darfst hoechstens die Haelfte der Steine wegnehmen! ");

		else if (result == Haufen.ERR_TOO_LESS)
			System.out.print ("FEHLER     : Du musst schon mindestens einen Stein wegnehmen! ");

		if (result != Haufen.ERR_NO_ERROR) {
			System.out.println ("Also nochmal.");
			benutzerZug ();
		} // endif

	} // benutzerZug ()

	/**
	  *  beendeSpiel () - Beendet das Spiel unter vorheriger Ausgabe der uebergebenen Meldung auf die Konsole.
	  *
	  *  @param msg Abschiedsmeldung als Zeichenkette
	  *  @return void
	  *
	  */

	private static void beendeSpiel (String msg) {

		System.out.println (msg);
		System.exit (0);

	} // beendeSpiel ()

	/**
	  *  benutzerFaengtAn () - Laesst den Zufallszahlengenerator entscheiden, ob der Benutzer oder
	  *  der Computer den ersten Zug hat (Zufallszahl 0 oder 1).
	  *
	  *  @return Boolescher Wert auf Zufallsbasis
	  *
	  */

	private static boolean benutzerFaengtAn () {

		return (gen.nextInt (2) == 0);

	} // benutzerFaengtAn ()

	/**
	  *  ausgabeSpielstand () - Gibt den aktuellen Spielstand (Anzahl Steine auf dem Haufen) auf
	  *  der Konsole aus.
	  *
	  *  @return void
	  *
	  */

	private static void ausgabeSpielstand () {

		System.out.print ("Spielstand : " + Haufen.getSpielstand () + " Stein");
		if (Haufen.getSpielstand () != 1)
			System.out.print ("e");
		System.out.println ("\n");

	} // ausgabeSpielstand ()

	/**
	  *  zugNummerAusgebenUndErhoehen () - Gibt die lfd. Nummer des aktuellen Spielzuges aus.
	  *
	  *  @return void
	  *
	  */

	private static void zugNummerAusgeben () {

		System.out.println ("**** ZUG Nummer " + nr_zug + " ****");

	} // zugNummerAusgebenUndErhoehen ()


	/** ***** PUBLIC METHODEN ***** */

	/**
	  *  main () - Main-Methode der Klasse "Spiel".
	  *
	  *  Realisiert den eigentlichen Spielablauf.
	  *
	  *  @param args Dieses Programm wertet keine Kommandozeilenparameter aus.
	  *
	  *  @return void
	  *
	  */

	public static void main (String[] args) throws IOException {

		/** Instantiiere zunŠchst die Klassen Haufen sowie Spieler */

		Haufen myHaufen = new Haufen ();
		Spieler myGegner = new Spieler ();

		/** Begruessung */

		System.out.println ("Hallo! Ich bin Dein Spielpartner und spiele heute im Modus \"" + myGegner.modusToString () + "\".");
		System.out.println ("Insgesamt haben wir " + myHaufen.getSpielstand () + " Steine zur Verfuegung!\n");

		/** Zentrale while()-Schleife */

		while (!myHaufen.istLeer ()) {

			/**
			  * Hier kommt der Benutzer zum Zug, falls es
			  *
			  * a) sich um den ersten Zug handelt und der Benutzer anfaengt, oder
			  * b) sich um einen spaeteren Zug (nr_zug > 1) handelt
			  *
			  */

			if (((nr_zug == 1) && (benutzerFaengtAn ())) || (nr_zug > 1)) {
				zugNummerAusgeben ();
				benutzerZug ();
				ausgabeSpielstand ();
				nr_zug++;
			}

			/** Falls an dieser Stelle der Haufen leer ist, hat ihn der Benutzer gerade geleert,
			  * und damit das Spiel verloren. */

			if (myHaufen.istLeer ())
				beendeSpiel ("---------------- GAME OVER!!! Du hast verloren. ----------------");

			/** Computer ist am Zug */

			zugNummerAusgeben ();
			System.out.println ("Computer   : Ich nehme " + myGegner.macheZug () + " Stein(e) weg.");
			ausgabeSpielstand ();
			nr_zug++;

			/** Sollte der Haufen gerade HIER leer werden, so hat der Computer ihn geleert und verloren. */

			if (myHaufen.istLeer ())
				beendeSpiel ("-------- WOW, YOU'VE WON!!! Der Computer hat verloren. ---------");

		} // endwhile

	} // main ()

} // Klasse Spiel
