package go; public class Game { private Go_IO IOInterface; private Board GameBoard; private Player player1; private Player player2; private AnalysisData player1AnalysisData; private AnalysisData player2AnalysisData; private int currentTurn; private boolean configured; private int capturedStonesPlayer1; private int capturedStonesPlayer2; private Originator originator; private Caretaker caretaker; public static final int DEBUGLEVEL = 0; public static final Class IOTYPE = Go_ConsoleIO.class; // constructor public Game() { // create instance of Go_IO class, initialize other objects/variables try { IOInterface = Go_IOFactory.getIOFactoryInstance().create(IOTYPE); } catch (GoIOInstanceException e) { e.printStackTrace(); } GameBoard = null; player1 = null; player2 = null; player1AnalysisData = new AnalysisData(); player2AnalysisData = new AnalysisData(); currentTurn = 0; configured = false; capturedStonesPlayer1 = 0; capturedStonesPlayer2 = 0; originator = null; caretaker = null; } public static void main(String args[]){ Game game = new Game(); game.startGame(); } // start this method from main to start the game public void startGame() { while (true) { // print main menu and save menu choice in "menu" int menu = IOInterface.getMenu(); // start the game if (menu == 1) { if (!configured) { getDefaultConfiguration(); configured = true; } originator = new Originator(); caretaker = new Caretaker(); configured = false; gameLoop(); } // configure the game else if (menu == 2) { getConfiguration(); configured = true; } } } // get game configuration (dimension, human/ai player) from user private void getConfiguration() { // get board dimension GameBoard = new Board(IOInterface.getDimension()); // initialize both players valid plays (all plays are valid in the beginning) player1AnalysisData.initValidPlays(GameBoard.getDimension()); player2AnalysisData.initValidPlays(GameBoard.getDimension()); // pass board to IO IOInterface.setBoard(GameBoard); // get players int player; // get player1 (player1 [black] starts the game) player = IOInterface.getPlayer(1); if (player == 1) { // create human player player1 = new Human(1); } else if (player == 2) { // create AI player player1 = new AI(1); } // get player2 player = IOInterface.getPlayer(2); if (player == 1) { // create human player player2 = new Human(2); } else if (player == 2) { // create AI player player2 = new AI(2); } // pass board and IO to both players player1.setBoard(GameBoard); player2.setBoard(GameBoard); // pass IO to both players ----> players can now get their own IO instance //player1.setIO(IOInterface); //player2.setIO(IOInterface); // initialize variables capturedStonesPlayer1 = 0; capturedStonesPlayer2 = 0; currentTurn = 0; } // default configuration: dimension = 9, HUMAN vs. AI private void getDefaultConfiguration() { // set board dimension final int DEFAULTDIMENSION = 9; GameBoard = new Board(DEFAULTDIMENSION); player1AnalysisData.initValidPlays(DEFAULTDIMENSION); player2AnalysisData.initValidPlays(DEFAULTDIMENSION); // pass board to IO IOInterface.setBoard(GameBoard); // get starting player int startingPlayer = IOInterface.getStartingPlayer(); // set players if (startingPlayer == 1) { player1 = new Human(1); player2 = new AI(2); } else { player1 = new AI(1); player2 = new Human(2); } // pass board to both players player1.setBoard(GameBoard); player2.setBoard(GameBoard); // pass IO to both players ---> players can now get their own IO instance //player1.setIO(IOInterface); //player2.setIO(IOInterface); // initialize variables capturedStonesPlayer1 = 0; capturedStonesPlayer2 = 0; currentTurn = 0; } private void gameLoop() { Boolean rungame = true; int currentPlayer = 1; save(); while (rungame) { if (DEBUGLEVEL == 1) { // debug(); } switch (currentPlayer) { case 1: IOInterface.printTurn(currentTurn); IOInterface.printCapturedStones(capturedStonesPlayer1, capturedStonesPlayer2); IOInterface.printBoard(); currentPlayer = makeTurn(currentPlayer); break; case 2: IOInterface.printTurn(currentTurn); IOInterface.printCapturedStones(capturedStonesPlayer1, capturedStonesPlayer2); IOInterface.printBoard(); currentPlayer = makeTurn(currentPlayer); break; case -3: // both passed endGame(); rungame = false; break; case -2: // player2 forfeited endGameForfeit(2); rungame = false; break; case -1: // player1 forfeited endGameForfeit(1); rungame = false; break; } } } private int makeTurn(int player) { currentTurn++; // player1 turn if (player == 1) { // get player1Status player1AnalysisData = player1.playTurn(player2AnalysisData.getValidPlays()); switch (player1AnalysisData.getPlayerStatus()) { // normal turn case 0: capturedStonesPlayer1 += player1AnalysisData.getCapturedStones(); save(); return 2; // pass case 1: // if both passed if (player2AnalysisData.getPlayerStatus() == 1) { // end the game return -3; } save(); return 2; // forfeit case 2: return -1; // undo case 3: // undo not allowed in turn 1 and 2 if (currentTurn <= 2) { IOInterface.printUndoError(); currentTurn--; // } else { undo(); } return 1; // no more valid plays case 4: IOInterface.printNoMoreValidPlaysMessage(1); // if both passed if (player2AnalysisData.getPlayerStatus() == 1) { // end the game return -3; } save(); return 2; } } // player2 turn else if (player == 2) { // get player2Status player2AnalysisData = player2.playTurn(player1AnalysisData.getValidPlays()); switch (player2AnalysisData.getPlayerStatus()) { // normal turn case 0: capturedStonesPlayer2 += player2AnalysisData.getCapturedStones(); save(); return 1; // pass case 1: // if both passed if (player1AnalysisData.getPlayerStatus() == 1) { // end the game return -3; } save(); return 1; // forfeit case 2: return -2; // undo case 3: // undo not allowed in turn 1 and 2 if (currentTurn <= 2) { IOInterface.printUndoError(); currentTurn--; } else { undo(); } return 2; // no more valid plays case 4: IOInterface.printNoMoreValidPlaysMessage(2); // if both passed if (player2AnalysisData.getPlayerStatus() == 1) { // end the game return -3; } save(); return 1; } } return 0; } private void undo() { Memento last = caretaker.getLastMemento(); originator.restoreFromMemento(last); GameBoard.overwrite(last.getSavedBoard()); player1AnalysisData.setValidPlays(GameBoard.getValidPlays(2)); player2AnalysisData.setValidPlays(GameBoard.getValidPlays(1)); GameBoard.getValidPlays(2); currentTurn = last.getSavedTurn(); capturedStonesPlayer1 = last.getSavedCapturedStonesForPlayer1(); capturedStonesPlayer2 = last.getSavedCapturedStonesForPlayer2(); } private void save() { // make deep copy of the current GameBoard and save that copy instead of the current board Board GameBoardCopy = new Board(GameBoard); originator.set(GameBoardCopy, currentTurn, capturedStonesPlayer1, capturedStonesPlayer2); Memento memento = originator.storeInMemento(); caretaker.addMemento(memento); } private void endGame() { double player1score = capturedStonesPlayer1; double player2score = 6.5 + capturedStonesPlayer2; IOInterface.printEndGameMessage(player1score, player2score); IOInterface.printBackToMenuMessage(); } private void endGameForfeit(int player) { IOInterface.printForfeitMessage(player); IOInterface.printBackToMenuMessage(); } /* private void debug() { System.err.print("savedMementos.size() = " + caretaker.savedMementosSize()); System.err.println(); System.err.print("Valid plays BLACK: "); for (int play : GameBoard.getValidPlays(1)) { System.err.print(play + " "); } System.err.println(); System.err.print("Valid plays WHITE: "); for (int play : GameBoard.getValidPlays(2)) { System.err.print(play + " "); } System.err.println(); System.err.print("Board Belegung: "); for (int i = 0; i < GameBoard.getDimension()*GameBoard.getDimension(); i++) { System.err.print(GameBoard.getStone(i).getColor() + " "); } System.err.println(); } */ }