Package ee.ttu.cs.iti0011.iabb104231.k1.Board

Source Code of ee.ttu.cs.iti0011.iabb104231.k1.Board.Board

package ee.ttu.cs.iti0011.iabb104231.k1.Board;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import ee.ttu.cs.iti0011.iabb104231.k1.Board.StateStorage.AbstractStateStorage;
import ee.ttu.cs.iti0011.iabb104231.k1.Board.StateStorage.BitSetStateStorage;
import ee.ttu.cs.iti0011.iabb104231.k1.Exceptions.NotYourMove;
import ee.ttu.cs.iti0011.iabb104231.k1.Exceptions.NumberOutOfRange;
import ee.ttu.cs.iti0011.iabb104231.k1.Exceptions.PlayerCantMoveTwice;
import ee.ttu.cs.iti0011.iabb104231.k1.Exceptions.PlayerNotSet;
import ee.ttu.cs.iti0011.iabb104231.k1.Exceptions.PositionIsAlreadyTaken;

import ee.ttu.cs.iti0011.iabb104231.k1.Player.AbstractPlayer;
import ee.ttu.cs.iti0011.iabb104231.k1.Renderer.AbstractRenderer;

public class Board
{
  private AbstractPlayer lastMove;
 
  private ArrayList<AbstractPlayer> players = new ArrayList<>();
 
  private AbstractPlayer startsFirst;
 
  private boolean gameStarted = false;
 
  private boolean finished = true;
 
  private AbstractRenderer renderer;
 
  private Map<AbstractPlayer, AbstractStateStorage> storages = new HashMap<AbstractPlayer, AbstractStateStorage>();
 
  private AbstractStateStorage storage;
 
 
  public Board()
  {
//    this(new IntegersMapStateStorage());
    this(new BitSetStateStorage());
  }
 
  public Board(AbstractStateStorage storage)
  {
    setStorage(storage);
  }
 
  public void output(String message)
  {
    System.out.println(message);
  }
 
  public void clear(){
    try{
      Runtime.getRuntime().exec("cls");
      Runtime.getRuntime().exec("clear");
    } catch(Exception e){
      for(int j = 0; j < 30; j++) {
        System.out.println();
      }

    }
  }
 
  public AbstractPlayer occupiedBy(Integer cell)
  {
    return getStorage().occupiedBy(cell);
  }
  private AbstractStateStorage getStorage() {
    return storage;
  }

  private void setStorage(AbstractStateStorage storage) {
    this.storage = storage;
  }

  /**
   * Add new player.
   * @param player
   */
  public void addPlayer(AbstractPlayer player)
  {
    player.setBoard(this);
    players.add(player);
    setPlayerStorage(player, player.getStorage());
  }
 
  /**
   * Get the list of players.
   * @return
   */
  public ArrayList<AbstractPlayer> getPlayers()
  {
    return players;
  }
 
  /**
   * Set player storage.
   * @param player
   * @param storage
   * @return
   */
  public Board setPlayerStorage(AbstractPlayer player, AbstractStateStorage storage)
  {
    storages.put(player, storage);
    return this;
  }
 
  public AbstractStateStorage getPlayerStorage(AbstractPlayer player)
  {
    return storages.get(player);
  }
 
  /**
   * Get all opened for move cells
   * @return
   */
  public ArrayList<Integer> getOpenCells()
  {
    return getStorage().getFreeCells();
  }

  public boolean isFinished()
  {
    return finished;
  }
 
  private void setLastMoved(AbstractPlayer player){
    lastMove = player;
  }
 
  /**
   * Starts the game
   */
  public void startTheGame()
  {
    finished = false;
   
    // Game is already running.
    if (gameStarted == true) {
      output("game is already started");
      System.exit(1);
    }
    output("Starting new game");
    gameStarted = true;
   
    Integer i = 0;
    while(!isFinished() && i < 10)
    {
      getRenderer().render();
      AbstractPlayer nextPlayer = whoIsNext();
      try{
        makeMove(nextPlayer, nextPlayer.yourNextMove());
      } catch(Exception e){
        output("ERROR !!!");
        output(e.getMessage());
        output(e.toString());
        e.printStackTrace();
      }
//      clear();
      i++;
    }
    getRenderer().render();
    getRenderer().renderTheWinner(getStorage().getWinner());
  }
 
  public AbstractPlayer whoStartsFirst()
  {
    if (startsFirst == null) {
      return players.get(0);
    }
    return startsFirst;
  }
 
  /**
   * Define, which player moves first.
   * By default, when game is started and no one is defined, the first added will start the game.
   * @param player
   * @throws PlayerNotSet
   */
  public void movesFirst(AbstractPlayer player) throws PlayerNotSet
  {
    if (!players.contains(player)) {
      throw new PlayerNotSet(player);
    }
  }
 
  /**
   * Get next player.
   * @todo - actually it's with bug - if more then two players will
   * play, it will not work :).... But anyway, when did you see more than
   * two players were playing this game ????
   * @return
   */
  public AbstractPlayer whoIsNext()
  {
    if (lastMove == null) {
      return whoStartsFirst();
    }
   
    for(AbstractPlayer player: players)
    {
      if (!player.equals(lastMove)) return player;
    }
    return null;
  }
 
  /**
   * Make player move.
   * @param player
   * @param cell
   */
  public void makeMove(AbstractPlayer player, Integer cell) throws PositionIsAlreadyTaken, PlayerCantMoveTwice, NumberOutOfRange, NotYourMove, Exception
  {
    output("Player: " + player.getName()  + " moves to " + cell);
   
    // There is no cell. end game
    if (getOpenCells().size() == 0) {
      finished = true;
      System.out.println("Game finished.");
      return;
    }
   
    // player can't move twice
    if (lastMove != null && player.equals(lastMove)) {
      throw new PlayerCantMoveTwice(player);
    }
   
    // It's not your turn
    if (!player.equals(whoIsNext())) {
      throw new NotYourMove(player);
    }
   
    // It's already taken
    if (!getStorage().cellIsEmpty(cell)){
      throw new PositionIsAlreadyTaken();
    }
   
    if (cell < 1 || cell > 9){
      throw new NumberOutOfRange();
    }
   
      getStorage().registerPlayerMove(player, cell);
      for(Map.Entry<AbstractPlayer, AbstractStateStorage> entry: storages.entrySet())
      {
        entry.getValue().registerPlayerMove(player, cell);
      }
      setLastMoved(player);
      if (getStorage().getWinner() != null) {
        finished = true;
      }
      if (getOpenCells().size() == 0) {
        finished = true;
      }
   
    return;
   
  }

  public AbstractRenderer getRenderer() {
    return renderer;
  }

  public void setRenderer(AbstractRenderer renderer) {
    renderer.setBoard(this);
    this.renderer = renderer;
  }
 
  public AbstractPlayer findWinner()
  {
    return getStorage().getWinner();
  }
 
}
TOP

Related Classes of ee.ttu.cs.iti0011.iabb104231.k1.Board.Board

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.