Package org.scotlandyard.impl.engine

Source Code of org.scotlandyard.impl.engine.GameImpl

package org.scotlandyard.impl.engine;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.scotlandyard.engine.Game;
import org.scotlandyard.engine.GameException;
import org.scotlandyard.engine.Token;
import org.scotlandyard.engine.User;
import org.scotlandyard.engine.boardmap.BoardMap;
import org.scotlandyard.engine.boardmap.Coordinate;
import org.scotlandyard.engine.boardmap.Link;
import org.scotlandyard.engine.constants.GameStatus;
import org.scotlandyard.engine.constants.TransportationMethod;
import org.scotlandyard.engine.player.Player;
import org.scotlandyard.engine.player.PlayerPosition;
import org.scotlandyard.impl.engine.player.Detective;
import org.scotlandyard.impl.engine.player.MrX;
import org.scotlandyard.utils.SetOperations;


/**
* implementation of the game object
*
* @author Hussain Al-Mutawa
* @version 1.0
* @since Sun Sep 18, 2011
*/
public final class GameImpl extends SetOperations implements Game {

  public static Game getNewInstance(final String identifier,
      final User creator, final BoardMap boardMap) throws GameException {
    final Game game = new GameImpl(identifier, creator, boardMap);

    if (creator!=null && GameEngine.instance().getUser(creator.getEmail()) == null) {
      throw new GameException(
          "the user can not create a game before login is made");
    }
    // add the game to the list of available games
    GameEngine.instance().getLobby().addGame(game);
    return game;
  }
  private BoardMap boardMap;
  private transient final User creator;
  private transient final Map<String, Detective> detectives;
  private GameStatus gameStatus;
  private transient final String identifier;
  private MrX mrX;
  private transient final Map<Player, PlayerPosition> playerPositions;
  private transient final Map<Player, EnumMap<TransportationMethod, Token>> playerTokens;

  private Player turn;

  /**
   * Construct a new Game object
   *
   * @param identifier
   * @param creator
   * @param boardMap
   */
  private GameImpl(final String identifier, final User creator,
      final BoardMap boardMap) {
    super();
    this.identifier = identifier;
    this.creator = creator;
    detectives = new HashMap<String, Detective>();
    playerPositions = new HashMap<Player, PlayerPosition>();
    this.boardMap = boardMap;
    gameStatus = GameStatus.JUST_CREATED;
    playerTokens = new HashMap<Player, EnumMap<TransportationMethod, Token>>();
  }

  @Override
  public void addDetective(final Detective detective) throws GameException {
    if (detective == null) {
      throw new GameException("Can not add a null detective to the list");
    }
    if (this.getPlayer(detective.getEmail()) != null) {
      throw new GameException("Can not join a game twice");
    }
    detectives.put(detective.getEmail(), detective);
    playerTokens.put(detective, new EnumMap<TransportationMethod, Token>(
        TransportationMethod.class));
  }

  @Override
  public int compareTo(final Game game) {
    return getIdentifier().compareTo(game.getIdentifier());
  }

  @Override
  public boolean equals(final Object other) {
    return toString().equals(other.toString());
  }

  @Override
  public Set<Coordinate> getAvailablePositions() {
    return SetOperations.difference(boardMap.getCoordinates(),
        getOccupiedPositions());
  }

  @Override
  public BoardMap getBoardMap() {
    return boardMap;
  }

  @Override
  public User getCreator() {
    return creator;
  }

  @Override
  public Set<Detective> getDetectives() {
    return new HashSet<Detective>(detectives.values());
  }

  @Override
  public GameStatus getGameStatus() {
    return gameStatus;
  }

  @Override
  public String getIdentifier() {
    return identifier;
  }

  @Override
  public MrX getMrX() {
    return mrX;
  }

  @Override
  public Set<Coordinate> getOccupiedPositions() {
    final Set<Coordinate> positions = new HashSet<Coordinate>();
    for (final PlayerPosition playerPosition : playerPositions.values()) {
      positions.add(playerPosition.getPosition());
    }
    return positions;
  }

  @Override
  public Player getPlayer(final String playerEmail) {
    Player player = null;
    if (this.getMrX() != null
        && this.getMrX().getEmail().equals(playerEmail)) {
      player = this.getMrX();
    } else {
      for (Detective d : this.getDetectives()) {
        if (d.getEmail().equals(playerEmail)) {
          player = d;
          break;
        }
      }
    }
    return player;
  }

  @Override
  public Coordinate getPlayerPosition(final Player player) {
    return playerPositions.get(player).getPosition();
  }

  @Override
  public Set<Player> getPlayers() {
    final Set<Player> players = new HashSet<Player>();
    players.addAll(detectives.values());
    if (mrX != null) {
      players.add(mrX);
    }
    return players;
  }

  @Override
  public Set<Coordinate> getPosssibleMoves(final Player player) {
    final Coordinate coordinate = getPlayerPosition(player);
    final Set<Link> links = boardMap.getLinks(coordinate);
    final Set<Coordinate> positions = new HashSet<Coordinate>();
    for (final Link link : links) {
      positions.add(link.getOtherEnd(coordinate));
    }
    return null; // TODO add getPossibleMoves
  }

  @Override
  public EnumMap<TransportationMethod, Token> getTokens(final Player player) {
    return playerTokens.get(player);
  }

  @Override
  public Player getTurn() {
    return turn;
  }


  public Player getWhoOccupiesPosition(final Coordinate coordinate) throws GameException {
    if(coordinate==null){
      throw new GameException("coordinate has not been initialized");
    }
    if(this.getBoardMap()==null){
      throw new GameException("the current board map for the game has not been initialized");
    }
    if(coordinate.getBoardMap()==null){
      throw new GameException("the board map of the coordinate has not been initialized yet");
    }
    if(!coordinate.getBoardMap().equals(this.getBoardMap())){
      throw new GameException("the board map of the coordinate ["+coordinate.getBoardMap().toString()+"] is"+
                  "the same as the board map of the game ["+this.getBoardMap().toString()+"]");
    }
    Player temp = null;
    for(Player player:this.getPlayers()){
      if(player.getPosition(this)!=null && player.getPosition(this).equals(coordinate)){
        temp=player;
      }
    }
    return temp;
  }

  @Override
  public Player getWhoOccupiesPosition(final String coordinateLabel) throws GameException {
    return getWhoOccupiesPosition(this.boardMap.getCoordinate(coordinateLabel));
  }
  public boolean hasPlayer(final String playerEmail) {
    boolean found = false;
    for (Player player : getPlayers()) {
      if (player.getEmail().equals(playerEmail)) {
        found = true;
        break;
      }
    }
    return found;
  }

  @Override
  public boolean removePlayer(final Player player) throws GameException{
    final MrX temp =null;
    if(player==null){
      throw new GameException("can not remove null player");
    }
    if (mrX!=null && mrX.getEmail().equals(player.getEmail())) {
      mrX=temp;
    } else {
      if(detectives.remove(player.getEmail())==null){
        throw new GameException("this player does not exist to be removed");
      }
    }
    playerPositions.remove(player);
    playerTokens.remove(player);

    return playerPositions.get(player)==null
        && playerTokens.get(player)==null
        && !hasPlayer(player.getEmail());
  }

  @Override
  public boolean removePlayer(final String playerEmail) throws GameException{
    final Player player = this.getPlayer(playerEmail);

    return removePlayer(player);
  }

  @Override
  public void setBoardMap(final BoardMap boardMap) {
    this.boardMap=boardMap;
  }

  @Override
  public void setGameStatus(final GameStatus gameStatus) {
    this.gameStatus = gameStatus;
  }

  @Override
  public void setMrX(final Player player) throws GameException {
    if (player != null && this.getPlayer(player.getEmail()) != null) {
      throw new GameException("Can not join a game twice");
    }
    if (mrX != null) {
      throw new GameException(
          "Mr X is already set, and shall not be changed");
    }
    mrX = (MrX) player;
  }

  @Override
  public void setPlayerPosition(final PlayerPosition playerPosition)
      throws GameException {
    if(playerPosition.getPlayer()==null){
      throw new GameException("player must be set");
    }
    if(playerPosition.getPosition()==null){
      throw new GameException("position can not be null");
    }
    if(playerPosition.getPosition().getBoardMap()==null){
      throw new GameException("position map must be set first");
    }
    if(!playerPosition.getPosition().getBoardMap().equals(this.getBoardMap())){
      throw new GameException("the map of the position ["+playerPosition.getPosition().getBoardMap().getName()+"] is different from the map of the game ["+this.getBoardMap().getName()+"]");
    }

    final Coordinate coordinate = playerPosition.getPosition();
    final Player player = this.getWhoOccupiesPosition(coordinate);

    if(player!=null){
      if(!getMrX().equals(player)){
        throw new GameException("this position has been already occupied by other detective");

      }else if(getMrX().equals(player) && !getMrX().equals(playerPosition.getPlayer())){
        //has Mr X been caught?
        this.playerPositions.put(playerPosition.getPlayer(), playerPosition);
        this.setGameStatus(GameStatus.FINISHED);
        throw new GameException("Game is finished, detective ["+playerPosition.getPlayer().getName()+"] has captured Mr X");
      }
    }
    playerPosition.getPlayer().setPosition(this, playerPosition.getPosition());
    this.playerPositions.put(playerPosition.getPlayer(), playerPosition);


  }



  @Override
  public void setPlayerPosition(final String playerEmail, final String coordinateLabel) throws GameException{
    if(gameStatus!=GameStatus.JUST_CREATED){
      throw new GameException("this method can be used to set players positions before the game has started only");
    }
    if(getPlayer(playerEmail)==null){
      throw new GameException("can not find player ["+playerEmail+"]");
    }
    if(this.getBoardMap()==null){
      throw new GameException("the map has not been set yet");
    }
    final Coordinate coordinate = this.getBoardMap().getCoordinate(coordinateLabel);
    if(coordinate==null){
      throw new GameException("can not find coordinate ["+coordinateLabel+"]");
    }
    final PlayerPosition playerPosition=new PlayerPositionImpl(this, this.getPlayer(playerEmail), this.boardMap.getCoordinate(coordinateLabel));
    this.setPlayerPosition(playerPosition);
  }

  @Override
  public void setTurn(final Player player) {
    turn = player;
  }

  @Override
  public String toString() {
    return "Game : " + getIdentifier();
  }

  @Override
  public boolean isPlayable() {
    boolean result=false;
    if(this.getGameStatus()==GameStatus.STARTED){
      result=true;
    }
    return result;
  }
 
 
  @Override
  public boolean isPositionOccupied(Coordinate coordinate) {
    for(PlayerPosition pp:this.playerPositions.values()){
      if(coordinate.equals(pp.getPosition())){
        return true;
      }
    }
    return false;
  }
 
  @Override
  public Coordinate getEmptyPosition() {
    Coordinate result=null;
    if(this.playerPositions.size()==this.getBoardMap().getCoordinates().size()){
      return result;
    }
    Iterator<Coordinate>it = this.getBoardMap().getCoordinates().iterator();
    while(result==null){
      result=it.next();
      if(this.isPositionOccupied(result)){
        result=null;
      }
    }
    return result;
  }

}
TOP

Related Classes of org.scotlandyard.impl.engine.GameImpl

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.