# TicTacToe vorgegebene interface->klassen aufbauen



## QuiXotiK (27. Apr 2015)

Hallo Java-user ich habe von meinem dozenten eine aufgabenstellung erhalten die folgendermaßen lautet:

"Bauen Sie Ihr Programm so um, daß es eine eigene Klasse für die Spieler gibt, die das vorgegebene Interface
game.Player implementiert. Die beiden für das Spiel nötigen Spieler sollen zur Laufzeit erzeugt werden.
Ihr Spiel muss das vorgegebene Interface game.Game implementieren. Nutzen Sie für die Darstellung der Spielzüge
das Interface game.Move aus der Vorgabe.
Nutzen Sie das Strategy-Pattern, um den Spielerinstanzen zur Laufzeit eine konkrete Spielstrategie mit dem
Interface strategy.GameStrategy mitzugeben, nach denen die Spieler ihre Züge berechnen.
Implementieren Sie mindestens drei unterschiedliche konkrete Strategien.
Nutzen Sie als weitere Strategie die Vorgabe zum Minimax-Algorithmus (strategy.MinMaxStrategy). Damit
steht eine stets perfekt spielende Spielstrategie zur Verfügung.
Stellen Sie die jetzt vorhandenen Klassen und ihre Beziehungen in einem manuell erstellten UMLKlassendiagramm
dar.
Hinweis: Ein Spieler soll seinen nächsten Zug nur berechnen und darf nicht direkt den Spielstand (Spielbrett)
modifizieren! Dies geschieht über die Methode game.doMove() aus dem Spiel (Interface game.Game). Die
Berechnung im Spieler wird direkt an die zur Laufzeit übergebene Strategie delegiert."

folgende interfaces wurden mitgeliefert:

```
package game;

import java.util.List;

public interface IGame {
	// Spieler X setzen
	void setPlayerX(IPlayer p);

	// Spieler O setzen
	void setPlayerO(IPlayer p);

	// Wer ist gerade dran?
	IPlayer currentPlayer();

	// Welche Zuege sind noch moeglich (aka freie Felder)
	List<IMove> remainingMoves();

	// Zug ausfuehren (Feld setzen), naechster Spieler ist "dran"
	void doMove(IMove m);

	// Zug zuruecknehmen (Feld setzen), voriger Spieler ist "dran"
	void undoMove(IMove m);

	// Spiel zuende?
	boolean ended();

	// Bewertung des Zustandes aus Sicht des Players p
	// +1: p hat gewonnen
	// -1: p hat verloren
	// 0: Unentschieden
	int evalState(IPlayer p);

	// Zeichne das aktuelle Feld auf der Konsole
	void printField();
}
```


```
package game;

public interface IMove {
	// Zeile auf dem Spielfeld
	public int getRow();

	// Spalte auf dem Spielfeld
	public int getColumn();
}
```


```
package game;

import strategy.IGameStrategy;

public interface IPlayer {
	// Spielstrategie setzen
	void setStrategy(IGameStrategy s);

	// Naechsten Zug berechnen (Delegation an Strategie!)
	IMove nextMove(IGame g);

	// Zeichen fuer den Spieler liefern
	char getSymbol();
}
```


```
package strategy;

import game.IGame;
import game.IMove;

public interface IGameStrategy {
	// Naechsten Zug berechnen
	IMove nextMove(IGame g);
}
```

langer text kurze frage.
wie genau handhabe ich die List<IMove> remainingMoves(), auf meine frage heute hatte er nur gesagt dass es nicht nötig ist die interfaces anzupassen und es sei auch nicht gewollt da dann cniht weiter mit testsuiten gearbeitet werden kann. außerdem habe ich auch noch irgendwie probleme die verbindung zwischen player.nextmove und game.domove bzw undomove. im grunde soll es ja so sein dass player.nextmove um den bestmöglichen zug herrauszufinden game.domove bzw undomove braucht also etwas in der richtung:

```
public IMove nextMove(IGame g) {
		//blabla
		g.doMove(irgendeinmove);
		//falls nicht bester move, rückgängig machen
		g.undoMove(letztermove);
		
		return bestermove;
	}
```
aber wie genau gehe ich das ganze dann im mainloop an.

```
while (game.ended() == false) {
			game.doMove(game.currentPlayer().nextMove(game));
		}
```
???
 normaleweise habe ich nicht wirklich probleme mit meinen programmieraufgaben aber meistens ist es auch der fall dass man selber was zusammenbasteln darf und man nicht an methoden gebunden ist


----------



## Saheeda (27. Apr 2015)

Hallo,

ich versuchs mal:

In der Player.nextMove würde ich mir die Liste aller noch möglichen Spielzüge holen und daraus den Bestmöglichen ermitteln und zurückgeben.
Das Setzen des Zuges selbst würde ich wieder in der Hauptklasse machen.


```
while(!game.ended()){	

			IMove nextMove = playerO.nextMove(game);
			
			game.doMove(nextMove);		

                      game.setPlayer(playerX);	
		}
```

game.undoMove hat meines Erachtens dort nirgendwo was verloren. Das würde ich im Fall einer GUI an einen "Zurück"-Button hängen oder den Benutzer vor jeder neuen Runde fragen, was er vor hat.


```
System.out.println("Was möchtest du tun?");
		
		String choice = new Scanner(System.in);
		switch(choice){
		case: "next";
		//nächsten Zug
		case: "undo";
		//undo ausführen
		default:
		}
```


Hilft das irgendwie?


----------



## QuiXotiK (27. Apr 2015)

vorweg vielen dank für die antwort..
zu deinem ersten codebeispiel:
wenn man deins und meins vergleicht ist es letzendlich ja das selbe.. mit currentplayer kriege ich den spieler zurück der grade an der reihe ist und außerdem noch shorthandmäßig aufgeschrieben.
gewechselt wird bei mir der player zum schluss der domove methode.

soweit ich meinen dozenten verstanden habe wird die undomethode gebraucht um den minimax zu realisieren, der testet halt alle züge durch wenn er mit einer partie fertig ist macht der so oft undo bis er da ist wo er angefangen hat und testet ein anderes szenario.

ziel dieser aufgabe war eig das strategypattern zu verinnerlichen, leider mit fiesem beigeschmack. ich habe also eine playerklasse die ein object vom typ gamestrategy hält und diese player ob x oder o delegiert dann an die nextmove der beinhaltenden objects.. das ist an sich net das problem, jedoch ist das ganze drumherum nichts was in meinen kopf gehen will


----------

