package game;
import engineControl.MovementControl;
import game.GameSettings.GameType;
import gui.Checkerboard;
import gui.Gui;
import java.util.ArrayList;
import java.util.List;
import rules.Rules;
import util.ChessfigureConstants;
import components.Field;
import components.Figure;
import components.FigureBishop;
import components.FigureKnight;
import components.FigureQueen;
import components.FigureRook;
/**
* Die "Hauptklasse" des Schachroboters, hier wird das Spiel gestartet.
*
* @author Florian Franke 23.10.2012
*
*/
public class GameCoordinator
{
/**
* Private Variable, die die Instanz des GameCoordinators enthält.
*/
private static GameCoordinator instance = null;
/**
* Enthaelt das Spielfeld
*/
public Field field;
/**
* Enthält alle Züge des aktuellen Spiels
*/
private List<Move> moves = new ArrayList<Move>();
/**
* Enthaelt den aktuellen Zug
*/
private Move currentMove = null;
/**
* Gui-Objekt
*/
private Gui gui;
/**
* Rules-Objekt
*/
private Rules rules = new Rules();
/**
* Roboter-Bewegung
*/
private MovementControl movementControl = null;
private boolean usingRobot = false;
/**
* Ist der aktuelle Zug der letzte?
*/
private boolean lastMove = false;
/**
* Sollen die Zuege etc. ausgegeben werden?
*/
private boolean logging = false;
/**
* Privater Konstruktor, damit nur eine Instanz vom GameCoordintor erstellt
* werden kann.
*/
private GameCoordinator(boolean logging) {
// Feld-Instanz holen
this.field = Field.getInstance();
// Logging?
this.logging = logging;
if (GameSettings.currentGameType == GameType.PlayerVsComputer ||
GameSettings.currentGameType == GameType.PlayerVsSimulatedComputer ||
GameSettings.currentGameType == GameType.SimulatedWithRobot) {
this.usingRobot = true;
this.movementControl = MovementControl.getInstance();
}
}
/**
* Gibt zurueck, ob das Spiel beendet ist.
*
* @return True: Spiel beendet; False: Spiel laeuft noch
*/
public boolean isEndOfGame() {
return this.lastMove;
}
/**
* Spiel zuende?
*/
public void setEndOfGame(boolean b)
{
this.lastMove = b;
}
/**
* Fuehrt einen Zug aus. Der Zug soll beim Aufruf gueltig sein!
*/
public void execMove() {
try {
// Zug ausgeben?
if (this.logging)
System.out.println(this.currentMove.getMoveAsText());
if (this.currentMove.isKingSideCastling()) {
// Gui soll Figur bewegen
this.gui.getCheckerboard().setCheckerboardInformation(this.currentMove);
if (this.currentMove.getPlayerColor() == ChessfigureConstants.WHITE) {
// Kurze weisse Rochade
// König versetzen
this.field.moveFigure(Field.getFieldNumber("e1"), Field.getFieldNumber("g1"));
// Turm versetzen
this.field.moveFigure(Field.getFieldNumber("h1"), Field.getFieldNumber("f1"));
} else if (this.currentMove.getPlayerColor() == ChessfigureConstants.BLACK) {
// Kurze schwarze Rochade
// König versetzen
this.field.moveFigure(Field.getFieldNumber("e8"), Field.getFieldNumber("g8"));
// Turm versetzen
this.field.moveFigure(Field.getFieldNumber("h8"), Field.getFieldNumber("f8"));
}
} else if (this.currentMove.isQueenSideCastling()) {
// Gui soll Figur bewegen
this.gui.getCheckerboard().setCheckerboardInformation(this.currentMove);
if (this.currentMove.getPlayerColor() == ChessfigureConstants.WHITE) {
// Lange weisse Rochade
// König versetzen
this.field.moveFigure(Field.getFieldNumber("e1"), Field.getFieldNumber("c1"));
// Turm versetzen
this.field.moveFigure(Field.getFieldNumber("a1"), Field.getFieldNumber("d1"));
} else if (this.currentMove.getPlayerColor() == ChessfigureConstants.BLACK) {
// Lange schwarze Rochade
// König versetzen
this.field.moveFigure(Field.getFieldNumber("e8"), Field.getFieldNumber("c8"));
// Turm versetzen
this.field.moveFigure(Field.getFieldNumber("a8"), Field.getFieldNumber("d8"));
}
} else {
// Wurde geschmissen?
if (this.currentMove.isCaptured()) {
// Geschmissene Figur vom Feld entfernen
this.field.removeFigureAt(this.currentMove.getFieldTo());
}
if (this.usingRobot) {
// Roboter soll Figur bewegen
if (this.movementControl == null) {
throw new Exception("Roboter-Instanz fehlt!");
}
if (this.currentMove.getPlayerColor() == ChessfigureConstants.BLACK) {
this.movementControl.setMovefigure(this.currentMove);
this.movementControl.moveRobot();
}
}
// Gui soll Figur bewegen
// Gui muss zuerst den Zug grafisch ausfuehren, da sie auf die
// Informationen des Feldes (fieldFrom) zugreift.
// Wuerde Field zuerst aktualisiert werden, koennte die Gui nicht
// mehr auf die zu versetzende Figur zugreifen!
this.gui.getCheckerboard().setCheckerboardInformation(this.currentMove);
// Bauer umgewandelt in...
Figure newFigure = null;
if (this.currentMove.isPawnPromotion()) {
if (this.currentMove.getPlayerColor() == ChessfigureConstants.WHITE) {
while (Checkerboard.getInstance().getPawnPromotionInformation() == 'A') {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.currentMove.setPawnPromotedTo(Checkerboard.getInstance().getPawnPromotionInformation());
}
if (this.currentMove.getPawnPromotedTo() == ChessfigureConstants.BISHOP_LETTER) {
newFigure = new FigureBishop(this.currentMove.getPlayerColor());
} else if (this.currentMove.getPawnPromotedTo() == ChessfigureConstants.KNIGHT_LETTER) {
newFigure = new FigureKnight(this.currentMove.getPlayerColor());
} else if (this.currentMove.getPawnPromotedTo() == ChessfigureConstants.QUEEN_LETTER) {
newFigure = new FigureQueen(this.currentMove.getPlayerColor());
} else if (this.currentMove.getPawnPromotedTo() == ChessfigureConstants.ROOK_LETTER) {
newFigure = new FigureRook(this.currentMove.getPlayerColor());
}
}
// Figur soll Zug durchfuehren
this.field.moveFigure(this.currentMove.getFieldFrom(),
this.currentMove.getFieldTo());
if (this.currentMove.isPawnPromotion()) {
this.field.removeFigureAt(this.currentMove.getFieldTo());
this.field.putFigureAt(this.currentMove.getFieldTo(), newFigure);
}
}
// War es der letzte Zug?
this.lastMove = this.currentMove.isCheckMate();
} catch (Exception e) {
System.out.println(e.getStackTrace()[0].getMethodName() + "(" + e.getStackTrace()[0].getClassName() + "): " + e.getMessage());
}
}
/**
* Neuer Zug wird dem aktuellen Spielverlauf hinzugefuegt. Entweder ein vom
* Spieler ausgefuerter Zug oder von der AI.
*
* @param newMove Der auszuführende Zug, er beinhaltet schon die Eigenschaften
* ob geschmissen wurde, ob eine Rochade stattfindet etc.
* @param checkThisMove Soll der uebergebene Zug auf Regeln geprüft werden?
* @return True: Gueltiger Zug wurde gespeichert; False: Ungueltiger Zug,
* Fehlermeldung anzeigen
*/
public boolean receiveMove(Move newMove, boolean checkThisMove)
{
if (checkThisMove) {
if (!this.rules.checkMove(this.field, newMove)) {
System.out.println("Ungültiger Zug laut Rules.checkMove().\nUngueltiger Zug: " + newMove.toString());
// Fehlermeldung anzeigen (GUI)
this.gui.showWarning("Ungültiger Zug!");
return false;
}
}
// currentMove aktualisieren
this.currentMove = newMove;
// Figurtyp bestimmen
this.currentMove.setFigure();
// Aktuellen Zug hinzufuegen
this.moves.add(this.currentMove);
return true;
}
/**
* Setzt die Gui
*
* @param gui
* GUI
*/
public void setGui(Gui gui) {
this.gui = gui;
}
/**
* Gibt alle Zuege des Spiels zurueck
*
* @return ArrayList mit allen Zuegen
*/
public List<Move> getAllMoves() {
return this.moves;
}
/**
* Um die Instanz des GameCoordinators zu holen.
*
* @return GameCoordinator-Instanz
*/
public static GameCoordinator getInstance(boolean logging) {
if (instance == null)
instance = new GameCoordinator(logging);
return instance;
}
}