Coverage Summary for Class: ViewPrinter (it.polimi.ingsw.view.CLI)

Class Class, % Method, % Line, %
ViewPrinter 0% (0/ 1) 0% (0/ 23) 0% (0/ 226)


1 package it.polimi.ingsw.view.CLI; 2  3 import com.google.gson.Gson; 4 import it.polimi.ingsw.utils.Observable; 5 import it.polimi.ingsw.utils.Observer; 6 import it.polimi.ingsw.utils.model.Command; 7 import it.polimi.ingsw.view.model.*; 8 import it.polimi.ingsw.view.socket.Parser; 9  10 import java.util.ArrayList; 11 import java.util.Arrays; 12 import java.util.List; 13 import java.util.stream.Collectors; 14 import java.util.stream.IntStream; 15  16 /** 17  * View Printer for CLI 18  */ 19 class ViewPrinter extends Observable<String> implements Observer<ArrayList<Command>> { 20  /** 21  * Player's username 22  */ 23  private String username; 24  /** 25  * Status if an update is needed due to server's update or some user's interaction 26  */ 27  private boolean needUpdate; 28  /** 29  * Data Parser 30  */ 31  private final Parser parser; 32  /** 33  * View Printer status 34  */ 35  private boolean status; 36  /** 37  * Last command that user has selected 38  */ 39  private Command lastCommand; 40  /** 41  * Set mode that the printer have to manage interaction with user 42  */ 43  private boolean confirmMode = false; 44  45  /** 46  * ViewPrinter Constructor 47  * 48  * @param parser data parser 49  */ 50  public ViewPrinter(Parser parser) { 51  this.parser = parser; 52  status = false; 53  needUpdate = false; 54  } 55  56  /** 57  * Set Status 58  * 59  * @param status status 60  */ 61  public void setStatus(boolean status) { 62  this.status = status; 63  printView(); 64  } 65  66  /** 67  * Set username 68  * 69  * @param username player username 70  */ 71  public void setUsername(String username) { 72  if (username == null || username.length() == 0) 73  throw new NullPointerException(); 74  this.username = username; 75  } 76  77  /** 78  * Clear console 79  */ 80  public static void clearConsole() { 81  System.out.print("\033[H\033[2J"); 82  System.out.flush(); 83  } 84  85  /** 86  * Create a string with the word centered 87  * 88  * @param space string length 89  * @param word word to be centered 90  * @return string of length space with the word centered 91  */ 92  private String centerFill(int space, String word) { 93  String out = String.format("%" + space + "s%s%" + space + "s", "", word, ""); 94  return out.substring((out.length() - space) / 2, (out.length() + space) / 2); 95  } 96  97  /** 98  * Print in console a list of string 99  * 100  * @param toPrint list of string to be printed 101  */ 102  private void printRow(ArrayList<String> toPrint) { 103  for (String x : toPrint) 104  System.out.format("%3s%s\n", "", x); 105  } 106  107  /** 108  * Make a collage between 2 arraylist of string cutting the first column of the 109  * second arraylist. Simply cat row per row, centering the content in the middle 110  * 111  * @param container_1 first arraylist of string 112  * @param container_2 second arraylist of string 113  * @return arraylist of previous two arraylist with a row per row cat and centered 114  * vertically 115  */ 116  private ArrayList<String> composeRow(ArrayList<String> container_1, ArrayList<String> container_2) { 117  String patternTop = container_1.get(0) + container_2.get(0).substring(1, container_2.get(0).length()); 118  String patternBottom = container_1.get(container_1.size() - 1) + container_2.get(container_2.size() - 1) 119  .substring(1, container_2.get(container_2.size() - 1).length()); 120  container_1.remove(0); 121  container_2.remove(0); 122  container_1.remove(container_1.size() - 1); 123  container_2.remove(container_2.size() - 1); 124  int maxH = Math.max(container_1.size(), container_2.size()); 125  ArrayList<String> toRes = new ArrayList<>(); 126  toRes.add(patternTop); 127  for (int index = 0; index < maxH; index++) { 128  String toAdd = ""; 129  if (index - (maxH - container_1.size()) / 2 >= 0 && index < (maxH + container_1.size()) / 2) 130  toAdd += container_1.get(index - (maxH - container_1.size()) / 2); 131  else 132  toAdd += "|" + String.format("%" + (container_1.get(0).length() - 1) + "s", "|"); 133  134  if (index - (maxH - container_2.size()) / 2 >= 0 && index < (maxH + container_2.size()) / 2) 135  toAdd += container_2.get(index - (maxH - container_2.size()) / 2).substring(1, 136  container_2.get(index - (maxH - container_2.size()) / 2).length()); 137  else 138  toAdd += String.format("%" + (container_2.get(0).length() - 1) + "s", "|"); 139  toRes.add(toAdd); 140  } 141  toRes.add(patternBottom); 142  return toRes; 143  } 144  145  /** 146  * Create a string 147  * 148  * @param space length of string 149  * @param start start char of the string 150  * @param end end char of the string 151  * @param fill fill of the string 152  * @param padding white space between start to fill and fill to end. 153  * @return string created 154  */ 155  private String breakRow(int space, String start, String end, String fill, int padding) { 156  String toRes = ""; 157  space -= 2 * (1 + padding); 158  for (int i = 0; i < space; i++) 159  toRes += fill; 160  toRes = toRes.substring(0, space); 161  if (padding == 0) 162  return start + toRes + end; 163  else 164  return String.format("%s%" + padding + "s%s%" + padding + "s%s", start, "", toRes, "", end); 165  } 166  167  /** 168  * Create a string 169  * 170  * @param space length of string 171  * @param start start char of the string 172  * @param end end char of the string 173  * @param fill fill of the string 174  * @return string created 175  */ 176  private String breakRow(int space, String start, String end, String fill) { 177  return breakRow(space, start, end, fill, 0); 178  } 179  180  /** 181  * Create an arraylist of string centering the content in the middle with a 182  * specific end and start char for each row 183  * 184  * @param toPrint arraylist of string to be centered 185  * @param space final length of each string 186  * @param start start char character 187  * @param end end char character 188  * @return arraylist of string created 189  */ 190  private ArrayList<String> composeRow(List<ArrayList<String>> toPrint, int space, String start, String end) { 191  ArrayList<String> toRes = new ArrayList<>(); 192  int maxH = toPrint.stream().map(e -> e.size()).max(Integer::compare).orElse(0); 193  toRes.add(breakRow(space + 1, start, end, " ")); 194  IntStream.range(0, maxH).forEachOrdered(index -> { 195  String toAdd = start; 196  for (ArrayList<String> x : toPrint) { 197  if (index - (maxH - x.size()) / 2 >= 0 && index < (maxH + x.size()) / 2) 198  toAdd += centerFill(space / toPrint.size() - 1, x.get(index - (maxH - x.size()) / 2)); 199  else 200  toAdd += centerFill(space / toPrint.size() - 1, ""); 201  toAdd += "|"; 202  } 203  toAdd = toAdd.substring(0, toAdd.length() - 1) + end; 204  toRes.add(toAdd); 205  }); 206  toRes.add(breakRow(space + 1, start, end, " ")); 207  return toRes; 208  } 209  210  /** 211  * Standard arraylist centering in the middle, with "|" as start and end char 212  * and a default string length equals to 90 213  * 214  * @param toPrint arraylist of string to be centered 215  * @return arraylist of string created 216  */ 217  private ArrayList<String> composeRow(List<ArrayList<String>> toPrint) { 218  return composeRow(toPrint, 90, "|", "|"); 219  } 220  221  /** 222  * Get Player's Info as an arraylist of string 223  * 224  * @return Player Info as an arraylist of string 225  */ 226  private ArrayList<String> getPlayerInfo() { 227  ArrayList<String> toRes = new ArrayList<>(); 228  toRes.addAll(composeRow(new ArrayList<>(Arrays.asList(new ArrayList<>(Arrays.asList("PLAYERS")))))); 229  List<ArrayList<String>> toPrint = parser.getPlayers().stream().map(e -> { 230  ArrayList<String> toRet = (ArrayList<String>) e.getRawData(); 231  if (e.getUsername().equals(username)) 232  toRet.add(0, "(You)"); 233  if (e.getUsername().equals(parser.getCurrentPlayer())) 234  toRet.add(0, "- Current Player -"); 235  return toRet; 236  }).collect(Collectors.toList()); 237  toRes.addAll(composeRow(toPrint)); 238  toRes.add(breakRow(91, "|", "|", "-", 3)); 239  return toRes; 240  } 241  242  /** 243  * Get Board Info as a arraylist of string 244  * 245  * @return Board Info as a arraylist of string 246  */ 247  private ArrayList<String> getBoardInfo() { 248  249  ArrayList<String> toRes = new ArrayList<>(); 250  toRes.addAll(composeRow(new ArrayList<>(Arrays.asList(new ArrayList<>(Arrays.asList("BOARD")))))); 251  Cell[][] toPrint = parser.getBoard(); 252  int position = 0; 253  for (Cell[] row : toPrint) { 254  ArrayList<ArrayList<String>> toPrintRow = new ArrayList<>(); 255  String braker = "|"; 256  for (Cell cell : row) { 257  ArrayList<String> toPush = (ArrayList<String>) cell.getRawData(); 258  toPush.add("[" + position + "]"); 259  toPrintRow.add(toPush); 260  braker += breakRow(19, "", " ", "-", 3); 261  position++; 262  } 263  braker = braker.substring(0, braker.length() - 1) + "|"; 264  // toRes.add(breakRow(121, "|", "|", "-", 3)); 265  toRes.addAll(composeRow(toPrintRow)); 266  267  toRes.add(braker); 268  } 269  return toRes; 270  } 271  272  /** 273  * Get Player's Action Info as a arraylist of string 274  * 275  * @return Player Action Info as a arraylist of string 276  */ 277  private ArrayList<String> getActionInfo() { 278  if (username == null) 279  return null; 280  int space = 12 * 7; 281  ArrayList<String> toRes = new ArrayList<>(); 282  toRes.add(breakRow(space + 1, ".", ".", "-")); 283  if (!parser.getGamePhase().equals("END") && username.equals(parser.getCurrentPlayer())) { 284  toRes.addAll(composeRow( 285  new ArrayList<>(Arrays.asList(new ArrayList<>(Arrays.asList("ACTIONS", "It's your turn!")))), space, 286  "|", "|")); 287  ArrayList<ArrayList<String>> toPrint = (ArrayList<ArrayList<String>>) parser.getUsableCommandList().stream() 288  .map(e -> { 289  ArrayList<String> toRet; 290  switch (e.getType()) { 291  case "action": 292  if (e.getInfo() == null) 293  toRet = new ArrayList<>(Arrays.asList("End Turn")); 294  else if (new Gson().fromJson(e.getInfo(), TypeAction.class).getTypeAction() 295  .equals("Swap")) 296  toRet = new Gson().fromJson(e.getInfo(), Swap.class).getRawData(); 297  else 298  toRet = (ArrayList<String>) new Gson().fromJson(e.getInfo(), Build.class) 299  .getRawData(); 300  break; 301  case "board": 302  toRet = (ArrayList<String>) new Gson().fromJson(e.getInfo(), Cell.class).getRawData(); 303  toRet.add("[" + e.getFuncData() + "]"); 304  break; 305  case "color": 306  toRet = (ArrayList<String>) new Color(e.getInfo()).getRawData(); 307  break; 308  case "god": 309  toRet = (ArrayList<String>) new God(e.getInfo()).getRawData(); 310  break; 311  case "godList": 312  toRet = (ArrayList<String>) new God(e.getInfo()).getRawData(); 313  break; 314  case "player": 315  toRet = (ArrayList<String>) new Gson().fromJson(e.getInfo(), Player.class).getRawData(); 316  break; 317  default: 318  toRet = null; 319  break; 320  } 321  return toRet; 322  }).filter(e -> e != null && e.size() > 0).collect(Collectors.toList()); 323  int indexAction = 0; 324  while (toPrint.size() > 0) { 325  List<ArrayList<String>> rowToPrint = (List<ArrayList<String>>) toPrint.subList(0, 326  toPrint.size() < 3 ? toPrint.size() : 3); 327  int i = 0; 328  for (ArrayList<String> x : rowToPrint) 329  x.add(0, "Action: " + (indexAction + i++)); 330  indexAction += rowToPrint.size(); 331  toRes.addAll(composeRow(rowToPrint, space, "|", "|")); 332  toRes.add(breakRow(space + 1, "|", "|", "-", 3)); 333  toPrint.subList(0, toPrint.size() < 3 ? toPrint.size() : 3).clear(); 334  } 335  toRes.remove(toRes.size() - 1); 336  } else if (parser.getPlayers().stream() 337  .anyMatch(e -> e.getUsername().equals(username) && e.getStatus().equals("WIN"))) { 338  ArrayList<String> winAsci = new ArrayList<>( 339  Arrays.asList("__ ___ ", "\\ \\ / (_) ", " \\ \\ /\\ / / _ _ __ ", 340  " \\ \\/ \\/ / | | '_ \\ ", " \\ /\\ / | | | | |", " \\/ \\/ |_|_| |_|")); 341  toRes.addAll(composeRow(new ArrayList<>(Arrays.asList(winAsci)), space, "|", "|")); 342  343  } else if (parser.getPlayers().stream() 344  .anyMatch(e -> e.getUsername().equals(username) && e.getStatus().equals("LOSE"))) { 345  ArrayList<String> loseAsci = new ArrayList<>( 346  Arrays.asList(" _ ", "| | ", "| | ___ ___ ___ ", 347  "| | / _ \\/ __|/ _ \\", "| |___| (_) \\__ \\ __/", "|______\\___/|___/\\___|")); 348  toRes.addAll(composeRow(new ArrayList<>(Arrays.asList(loseAsci)), space, "|", "|")); 349  } else { 350  toRes.addAll(composeRow( 351  new ArrayList<>(Arrays.asList(new ArrayList<>(Arrays.asList("ACTIONS", "It's not your turn!")))), 352  space, "|", "|")); 353  } 354  toRes.add(breakRow(space + 1, "'", "'", "-")); 355  return toRes; 356  } 357  358  /** 359  * Get a Player Action Command based on the index 360  * 361  * @param index command index 362  * @return command selected, otherwise null 363  */ 364  private Command getActionString(int index) { 365  try { 366  return parser.getUsableCommandList().get(index); 367  } catch (Exception e) { 368  return null; 369  } 370  } 371  372  /** 373  * Use a Player Action Command based on the index 374  * 375  * @param index command index 376  */ 377  public void useAction(String index) { 378  index = index.trim(); 379  if (index.toUpperCase().equals("QUIT")) { 380  status = false; 381  return; 382  } 383  needUpdate = true; 384  Command toSend = null; 385  try { 386  toSend = getActionString(Integer.parseInt(index)); 387  if (toSend != null && (toSend.getFuncName().equals("setGodList") || toSend.getFuncName().equals("setGod")) 388  && (lastCommand == null || !new Gson().toJson(lastCommand).equals(new Gson().toJson(toSend)))) { 389  confirmMode = true; 390  printView(); 391  System.out.print("\n God " + toSend.getFuncData() + " effect:\n\n " 392  + GodEffect.strConverter(toSend.getFuncData()).getEffect() 393  + "\n\n Retype action code to confirm or Type another God to change: "); 394  lastCommand = toSend; 395  return; 396  } 397  confirmMode = false; 398  } catch (Exception e) { 399  // fail parse 400  } 401  if (toSend != null) 402  notify(Parser.toString(toSend)); 403  else 404  printView(); 405  } 406  407  /** 408  * Print view 409  */ 410  private synchronized void printView() { 411  if (!needUpdate || !status) 412  return; 413  needUpdate = false; 414  clearConsole(); 415  416  printLogo(); 417  ArrayList<String> gameInfo, Actions; 418  gameInfo = new ArrayList<>(Arrays.asList(breakRow(91, ".", ".", "-"))); 419  // gameInfo.addAll(printGameInfo()); 420  gameInfo.addAll(getPlayerInfo()); 421  gameInfo.addAll(getBoardInfo()); 422  gameInfo.remove(gameInfo.size() - 1); 423  gameInfo.add(breakRow(91, "'", "'", "-")); 424  Actions = getActionInfo(); 425  426  if (Actions != null) 427  printRow(composeRow(gameInfo, Actions)); 428  else 429  printRow(gameInfo); 430  431  if (parser.getGamePhase().equals("END")) 432  System.out.println(" Game ended"); 433  434  System.out.print(" Type QUIT to exit from the game\n "); 435  436  if (!confirmMode && username.equals(parser.getCurrentPlayer()) && !parser.getGamePhase().equals("END")) 437  System.out.print(" Type Action number: "); 438  439  if (!username.equals(parser.getCurrentPlayer()) 440  && (parser.getGamePhase().equals("SET_GOD_LIST") || parser.getGamePhase().equals("CHOOSE_GOD"))) { 441  List<Command> godList = parser.getCommandList("godList"); 442  if (godList.size() == 0) 443  return; 444  System.out.println("\n God to use in this Game:"); 445  parser.getCommandList("godList").forEach(e -> { 446  System.out.println( 447  "\n God " + e.getInfo() + "\n\n " + GodEffect.strConverter(e.getInfo()).getEffect()); 448  }); 449  } 450  } 451  452  @Override 453  public void update(ArrayList<Command> message) { 454  // System.out.println("view: "+ message); 455  if (message == null || message.size() == 0) 456  return; 457  needUpdate = true; 458  printView(); 459  } 460  461  /** 462  * Print Logo 463  */ 464  public static void printLogo() { 465  ArrayList<String> logoAsci = new ArrayList<>(Arrays.asList( 466  " .----------------. .----------------. .-----------------. .----------------. .----------------. .----------------. .----------------. .-----------------. .----------------. ", 467  " | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |", 468  " | | _______ | || | __ | || | ____ _____ | || | _________ | || | ____ | || | _______ | || | _____ | || | ____ _____ | || | _____ | |", 469  " | | / ___ | | || | / \\ | || ||_ \\|_ _| | || | | _ _ | | || | .' `. | || | |_ __ \\ | || | |_ _| | || ||_ \\|_ _| | || | |_ _| | |", 470  " | | | (__ \\_| | || | / /\\ \\ | || | | \\ | | | || | |_/ | | \\_| | || | / .--. \\ | || | | |__) | | || | | | | || | | \\ | | | || | | | | |", 471  " | | '.___`-. | || | / ____ \\ | || | | |\\ \\| | | || | | | | || | | | | | | || | | __ / | || | | | | || | | |\\ \\| | | || | | | | |", 472  " | | |`\\____) | | || | _/ / \\ \\_ | || | _| |_\\ |_ | || | _| |_ | || | \\ `--' / | || | _| | \\ \\_ | || | _| |_ | || | _| |_\\ |_ | || | _| |_ | |", 473  " | | |_______.' | || ||____| |____|| || ||_____|\\____| | || | |_____| | || | `.____.' | || | |____| |___| | || | |_____| | || ||_____|\\____| | || | |_____| | |", 474  " | | | || | | || | | || | | || | | || | | || | | || | | || | | |", 475  " | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |", 476  " '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' ")); 477  System.out.print("\n\n"); 478  for (String x : logoAsci) 479  System.out.println(x); 480  System.out.print("\n\n"); 481  482  } 483 }