Coverage Summary for Class: Game (it.polimi.ingsw.model)

Class Class, % Method, % Line, %
Game 100% (1/ 1) 100% (22/ 22) 100% (106/ 106)


1 package it.polimi.ingsw.model; 2  3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.List; 6 import java.util.Objects; 7 import java.util.Random; 8 import java.util.stream.Collectors; 9  10 /** 11  * This is the Game Class, it is used to manage the data of the game. 12  */ 13 public class Game { 14  /** 15  * GameMode of this game 16  */ 17  public final GameMode mode; 18  /** 19  * Current GamePhase 20  */ 21  private GamePhase phase; 22  /** 23  * Players List 24  */ 25  private List<Player> playerList; 26  /** 27  * Current Player index 28  */ 29  private int player; 30  /** 31  * Gods List used in this game 32  */ 33  private List<God> godList; 34  /** 35  * Instance of the Game Board 36  */ 37  private final IslandBoard islandBoard; 38  39  /** 40  * Create a new game with the specified mode and players 41  * 42  * @param mode the game mode 43  * @param players all players'username 44  * @exception IllegalArgumentException if repeated username or wrong number of 45  * players 46  */ 47  public Game(GameMode mode, List<String> players) { 48  godList = new ArrayList<>(); 49  if (players.stream().distinct().collect(Collectors.toList()).size() == players.size() 50  && players.size() == mode.getPlayersNum()) 51  playerList = players.stream().map(Player::new).collect(Collectors.toList()); 52  else 53  throw new IllegalArgumentException(); 54  55  this.mode = mode; 56  islandBoard = new IslandBoard(); 57  phase = GamePhase.start(); 58  player = new Random().nextInt(playerList.size()); 59  playerList.get(player).setStatusPlayer(StatusPlayer.GAMING); 60  } 61  62  /** 63  * Check if the current player can end the turn 64  * 65  * @return True if can end turn, otherwise False 66  */ 67  public boolean canEndTurn() { 68  return islandBoard.canEndTurn(); 69  } 70  71  /** 72  * Get current Game Phase 73  * 74  * @return current GamePhase 75  */ 76  public GamePhase getPhase() { 77  return phase; 78  } 79  80  /** 81  * Get Current Player's username 82  * 83  * @return current player's username 84  */ 85  public String getCurrentPlayer() { 86  return playerList.get(player).getUsername(); 87  } 88  89  /** 90  * 91  * Get a copy of Game PlayerList 92  * 93  * @return a copy of current players list 94  */ 95  public ArrayList<Player> getPlayerList() { 96  return (ArrayList<Player>) playerList.stream().map(Player::new).collect(Collectors.toList()); 97  } 98  99  /** 100  * Get a copy of Gods used in this game 101  * 102  * @return a copy of current gods list for the game 103  */ 104  public ArrayList<God> getGodList() { 105  return (ArrayList<God>) godList.stream().map(e -> e).collect(Collectors.toList()); 106  } 107  108  /** 109  * Get a copy of the Game Board 110  * 111  * @return a copy of current game board 112  */ 113  public Cell[][] getBoard() { 114  return islandBoard.getBoard(); 115  } 116  117  /** 118  * Get a copy of available actions for the player in this turn 119  * 120  * @return a copy of available actions for the player in this turn 121  */ 122  public Action[][][] getActions() { 123  return islandBoard.getActions(); 124  } 125  126  /** 127  * End the current game. It sets all players in IDLE mode if not WIN or LOSE 128  */ 129  public void quitPlayer() { 130  playerList = playerList.stream().map(e -> { 131  if (e.getStatusPlayer() == StatusPlayer.GAMING) 132  e.setStatusPlayer(StatusPlayer.IDLE); 133  return e; 134  }).collect(Collectors.toList()); 135  phase = GamePhase.END; 136  } 137  138  /** 139  * Shift to the next player, if only one player remains, his status will be set as 'WIN'. The player 140  * also 'WIN' if all other players has status as 'LOSE' 141  */ 142  private void nextPlayer() { 143  144  // Set all player except the Winner to Lose StaturPlayer and set the Winner to 145  // IDLE state 146  if (playerList.get(player).getStatusPlayer() == StatusPlayer.WIN) { 147  playerList = playerList.stream().map(e -> { 148  if (e.getStatusPlayer() != StatusPlayer.WIN) 149  e.setStatusPlayer(StatusPlayer.LOSE); 150  else 151  e.setStatusPlayer(StatusPlayer.IDLE); 152  return e; 153  }).collect(Collectors.toList()); 154  } 155  156  // If the current player is not LOSE then it is changed to IDLE 157  if (playerList.get(player).getStatusPlayer() != StatusPlayer.LOSE) 158  playerList.get(player).setStatusPlayer(StatusPlayer.IDLE); 159  160  // If there are at least 2 player on IDLE State, then search for the first 161  // player on IDLE state, otherwise set the only player to WINNER 162  if (playerList.stream().filter(e -> e.getStatusPlayer() == StatusPlayer.IDLE).collect(Collectors.toList()) 163  .size() > 1) { 164  // at least 2 player IDLE 165  while ((player = (player + 1) % playerList.size()) >= 0 166  && playerList.get(player).getStatusPlayer() != StatusPlayer.IDLE) { 167  } 168  playerList.get(player).setStatusPlayer(StatusPlayer.GAMING); 169  } else { 170  playerList = playerList.stream().map(e -> { 171  if (e.getStatusPlayer() == StatusPlayer.IDLE) 172  e.setStatusPlayer(StatusPlayer.WIN); 173  return e; 174  }).collect(Collectors.toList()); 175  player = playerList.indexOf(playerList.stream().filter(e -> e.getStatusPlayer() == StatusPlayer.WIN) 176  .collect(Collectors.toList()).get(0)); 177  phase = GamePhase.END; 178  } 179  } 180  181  /** 182  * Get available colors to pick 183  * 184  * @return current free color 185  */ 186  public List<Color> getColors() { 187  List<Color> chosenColor = playerList.stream().map(Player::getColor).filter(Objects::nonNull) 188  .collect(Collectors.toList()); 189  return Arrays.stream(Color.values()).filter(c -> !chosenColor.contains(c)).collect(Collectors.toList()); 190  } 191  192  /** 193  * Set the god for the current player 194  * 195  * @param god god to set 196  */ 197  public void setGod(God god) { 198  islandBoard.addGod(getCurrentPlayer(), god); 199  playerList.get(player).setGod(god); 200  godList = godList.stream().filter(e -> e != god).collect(Collectors.toList()); 201  202  if (!godList.isEmpty()) 203  nextPlayer(); 204  205  if (godList.size() == 1) { 206  setGod(godList.get(0)); 207  phase = phase.next(); 208  } 209  } 210  211  /** 212  * Set gods to use in this game (one god at the time) 213  * 214  * @param god god to set 215  */ 216  public void setGodList(God god) { 217  godList.add(god); 218  if (godList.size() == mode.getPlayersNum()) { 219  phase = phase.next(); 220  nextPlayer(); 221  } 222  } 223  224  /** 225  * Set color for current player 226  * 227  * @param color chosen color 228  */ 229  public void setColor(Color color) { 230  playerList.get(player).setColor(color); 231  phase = phase.next(); 232  } 233  234  /** 235  * Set/Place a worker for current player 236  * 237  * @param position worker position in ( row * 5 + col ) format, 0 <= position < 238  * 25 239  */ 240  public void setWorkers(int position) { 241  int remainWorker = playerList.get(player).placeWoker(); 242  islandBoard.addWorker(getCurrentPlayer(), playerList.get(player).getColor(), 243  new int[] { position / 5, position % 5 }); 244  if (remainWorker == 0) { 245  nextPlayer(); 246  if (playerList.get(player).getColor() == null) 247  phase = phase.prev(); 248  else 249  phase = phase.next(); 250  } 251  } 252  253  /** 254  * Choose a worker for current player 255  * 256  * @param position worker position in (row * 5 + col) format, 0 <= position < 25 257  */ 258  public void chooseWorker(int position) { 259  islandBoard.chooseWorker(getCurrentPlayer(), new int[] { position / 5, position % 5 }); 260  if (phase == GamePhase.CHOOSE_WORKER) 261  phase = phase.next(); 262  } 263  264  /** 265  * Use an action for current player 266  * 267  * @param position action position in [(row * 5 + col), dim] format, 0 <= (row * 268  * 5 + col) < 25 and 0 <= dim < 3 269  */ 270  public void chooseAction(int[] position) { 271  if (phase == GamePhase.PENDING && position != null) 272  phase = phase.next(); 273  274  ReportAction reportAction = islandBoard.executeAction(playerList.get(player).getUsername(), 275  position == null ? null : new int[] { position[0] / 5, position[0] % 5, position[1] }); 276  playerList.get(player).setStatusPlayer(reportAction.getStatusPlayer()); 277  autoEnd(); 278  } 279  280  /** 281  * Try to perform an auto-end action until a new player can play 282  */ 283  private void autoEnd() { 284  if (playerList.get(player).getStatusPlayer() == StatusPlayer.GAMING) 285  return; 286  287  phase = GamePhase.CHOOSE_WORKER; 288  nextPlayer(); 289  290  if (playerList.get(player).getStatusPlayer() == StatusPlayer.GAMING) 291  playerList.get(player).setStatusPlayer( 292  islandBoard.executeAction(playerList.get(player).getUsername(), null).getStatusPlayer()); 293  294  if (playerList.get(player).getStatusPlayer() != StatusPlayer.WIN) 295  autoEnd(); 296  } 297  298  /** 299  * Set start player 300  * 301  * @param targetUsername start player username 302  * @exception IndexOutOfBoundsException if username not exists 303  */ 304  public void choosePlayer(String targetUsername) { 305  playerList.get(player).setStatusPlayer(StatusPlayer.IDLE); 306  player = playerList.indexOf(playerList.stream().filter(e -> e.getUsername().equals(targetUsername)) 307  .collect(Collectors.toList()).get(0)); 308  playerList.get(player).setStatusPlayer(StatusPlayer.GAMING); 309  phase = phase.next(); 310  } 311  312 }