package Factory.GameLogic; import EnvironmentPluginAPI.Exceptions.IllegalActionException; import EnvironmentPluginAPI.Exceptions.IllegalNumberOfClientsException; import EnvironmentPluginAPI.Exceptions.TechnicalException; import EnvironmentPluginAPI.TransportTypes.TMapMetaData; import Factory.GameLogic.Enums.Direction; import Factory.GameLogic.Exceptions.NoUnitFoundException; import Factory.GameLogic.GameActors.AbstractField; import Factory.GameLogic.GameActors.Factory; import Factory.GameLogic.GameActors.Player; import Factory.GameLogic.GameActors.Unit; import Factory.GameLogic.TransportTypes.*; import java.util.*; /** * Created with IntelliJ IDEA. * User: TwiG * Date: 13.05.12 * Time: 19:35 * To change this template use File | Settings | File Templates. */ public class Game extends Observable implements java.io.Serializable { // ------------------------------ FIELDS ------------------------------ private Player activePlayer; public Player getActivePlayer() { return activePlayer; } private Player winningPlayer = null; public Player getWinningPlayer() { return winningPlayer; } private Date gameStartedAt; private List<Factory> factories = new ArrayList<Factory>(); public List<Factory> getFactories() { return factories; } private AbstractField[][] board; public AbstractField[][] getBoard() { return board; } private RuleBook ruleBook = new RuleBook(); private List<Player> players; private TMapMetaData mapMetaData; public TMapMetaData getMapMetaData() { return mapMetaData; } private int turn = 1; public int getTurn() { return turn; } private int round = 1; public int getRound() { return round; } private MapGenerator mapGenerator; private List<TGameState> turns; // --------------------------- CONSTRUCTORS --------------------------- public Game(TMapMetaData mapMetaData, List<Player> players) throws IllegalNumberOfClientsException { if (players.size() < 2) { throw new IllegalNumberOfClientsException("There were less than 2 players in the list. Please choose exactly two."); } else if(players.size() > 2) { throw new IllegalNumberOfClientsException("There were more than 2 players in the list. Please choose exactly two."); } Random rand = new Random(); this.players = players; this.mapMetaData = mapMetaData; mapGenerator = new MapGenerator(mapMetaData, factories); activePlayer = players.get(rand.nextInt(players.size())); this.board = mapGenerator.generateMap(); gameStartedAt = new Date(); this.turns = new LinkedList<TGameState>(); for (Factory factory : factories) { this.addObserver(factory); } } // ------------------------ CANONICAL METHODS ------------------------ @Override public String toString() { String display = ""; String endOfLine = "\n"; for (int i = 0; i < mapMetaData.getEdgeLength(); i++) { for (int j = 0; j < mapMetaData.getEdgeLength(); j++) { display += board[i][j].toString(); } display += endOfLine; } return display; } // -------------------------- PUBLIC METHODS -------------------------- public void executeActionList(TActionsInTurn actionsInTurn) throws TechnicalException { for (TAction action : actionsInTurn) { moveUnit(action.getUnit(), action.getDirection()); } endTurn(); //System.out.println(this.toString()); } public boolean moveUnit(TUnit tUnit, Direction direction) { Unit unit = getUnitForID(tUnit.getUnitId()); TPosition unitPosition; if (ruleBook.validateMoveUnit(activePlayer.getFaction(), unit, direction, this)) { unitPosition = getPositionForUnit(unit); board[unitPosition.getY()][unitPosition.getX()].removeOccupant(); getNeighborFieldForPosition(unitPosition, direction).setOccupant(unit); unit.calculateExhaustion(turn); return true; } else { return false; } } Unit getUnitForID(UUID ID) { for (AbstractField[] fields : board) { for (AbstractField field : fields) { if (field.isOccupied()) { if (field.getOccupant().getUnitID().equals(ID)) { return field.getOccupant(); } } } } //no unit found! throw new NoUnitFoundException("No unit with the given GUID: " + ID.toString() + " was found :(."); } public TPosition getPositionForUnit(Unit unit) { if (unit == null) { throw new IllegalActionException("The given unit was null."); } for (int x = 0; x < mapMetaData.getEdgeLength(); x++) { for (int y = 0; y < mapMetaData.getEdgeLength(); y++) { if (board[y][x].isOccupied()) { if (board[y][x].getOccupant().getUnitID().equals(unit.getUnitID())) { return new TPosition(x, y); } } } } //No unit was found Something bad will happen return null; } public void endTurn() throws TechnicalException { if (ruleBook.validateEndTurn(this)) { turn += 1; roundUpdate(); if (winningPlayer == null) { winningPlayer = ruleBook.validateWinner(this); } List<TFactory> tFactories = new ArrayList<TFactory>(); TAbstractField[][] tAbstractFields = new TAbstractField[board.length][board[0].length]; for (Factory f : factories) { tFactories.add(f.getTransportType()); } for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { tAbstractFields[i][j] = board[i][j].getTransportType(); } } boolean playerWon = false; if (winningPlayer != null) { playerWon = true; } turns.add(new TGameState(playerWon, activePlayer.getTransportType(), turn, round, gameStartedAt, tFactories, tAbstractFields)); setChanged(); notifyObservers(EventTyp.END_TURN); switchActivePlayer(); } else { throw new IllegalActionException("rules of factory broken!"); } } private void roundUpdate() { int isNewRound = turn % 2; round += isNewRound; if (isNewRound == 1) { setChanged(); notifyObservers(EventTyp.END_ROUND); } } private void switchActivePlayer() { if (activePlayer == players.get(0)) activePlayer = players.get(1); else activePlayer = players.get(0); } public boolean gameFinished() { return winningPlayer != null; } public TGameState getCurrentGameState() throws TechnicalException { List<TFactory> tFactories = new ArrayList<TFactory>(); for (Factory factory : factories) { tFactories.add(factory.getTransportType()); } tFactories = Collections.unmodifiableList(tFactories); TAbstractField[][] tBoard = new TAbstractField[board.length][board[0].length]; for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { tBoard[i][j] = board[i][j].getTransportType(); } } boolean playerwon = false; if (winningPlayer != null) { playerwon = true; } return new TGameState(playerwon, activePlayer.getTransportType(), turn, round, gameStartedAt, tFactories, tBoard); } public AbstractField getFieldForPosition(TPosition position) { return board[position.getY()][position.getX()]; } public AbstractField getNeighborFieldForPosition(TPosition position, Direction direction) { int x = position.getX(); int y = position.getY(); switch (direction) { case UP: return board[y - 1][x]; case DOWN: return board[y + 1][x]; case LEFT: return board[y][x - 1]; case RIGHT: return board[y][x + 1]; case UP_LEFT: return board[y - 1][x - 1]; case UP_RIGHT: return board[y - 1][x + 1]; case DOWN_LEFT: return board[y + 1][x - 1]; case DOWN_RIGHT: return board[y + 1][x + 1]; } return null; } public TGameReplay getReplay() { List<String> playerNames = new ArrayList<String>(); for (Player p : this.players) { playerNames.add(p.getName()); } return new TGameReplay(UUID.randomUUID(), this.gameStartedAt, playerNames, this.winningPlayer.getName(), this.turn, this.turns); } }