Coverage Summary for Class: PlayerBoardUI (it.polimi.ingsw.Client.CLI)
Class |
Method, %
|
Branch, %
|
Line, %
|
PlayerBoardUI |
0%
(0/6)
|
0%
(0/35)
|
0%
(0/58)
|
PlayerBoardUI$1 |
0%
(0/1)
|
0%
(0/1)
|
Total |
0%
(0/7)
|
0%
(0/35)
|
0%
(0/59)
|
1 package it.polimi.ingsw.Client.CLI;
2
3 import it.polimi.ingsw.Misc.OptionalValue;
4 import it.polimi.ingsw.Misc.Symbols;
5 import it.polimi.ingsw.Model.Enums.GameMode;
6 import it.polimi.ingsw.Model.Enums.PawnColour;
7 import it.polimi.ingsw.Model.Model;
8 import it.polimi.ingsw.Model.PlayerBoard;
9
10 /**
11 * PlayerBoardUI allows to print all the information representing the {@link PlayerBoard}.
12 * <br>
13 * It exposes multiple methods to render the individual components independently and one method to combine them all
14 * in a single component.
15 */
16 public class PlayerBoardUI {
17
18 /**
19 * It draws a representation of the {@link PlayerBoard} of the provided player.
20 *
21 * @param playerBoard the {@link PlayerBoard} which will be represented
22 * @param ctx reference to the model used to check the available coins left in the game
23 * @return the complete player board UI component
24 */
25 public static String drawPlayerBoard(PlayerBoard playerBoard, Model ctx) {
26 StringBuilder screen = new StringBuilder();
27 boolean isCurrentPlayer = ctx.getMutableTurnOrder().getMutableCurrentPlayer().equals(playerBoard);
28 // Playerboard sections' titles. Change the argument of repeat() to further separate islands from playerboards
29 screen.append("\n".repeat(1)).append("Entrance:\t").append("Dining Room:\t\t").append("Teachers:\t").append("Towers:\t\t");
30 // Coins should be printed only if game mode is advanced
31 if (ctx.getGameMode() == GameMode.ADVANCED) {
32 screen
33 .append("Coins available:").append(playerBoard.getCoinBalance())
34 // add tip to remind usage of showActions command
35 .append(isCurrentPlayer ? InfoUI.showActions() : "").append("\n");
36 } else {
37 // add tip to remind usage of showActions command
38 screen.append(isCurrentPlayer ? InfoUI.showActions() : "").append("\n");
39 }
40
41 String entrance = PlayerBoardUI.drawEntrance(playerBoard, ctx);
42 String towers = PlayerBoardUI.drawTowers(playerBoard, ctx);
43 for (PawnColour p : PawnColour.values()) {
44 // This will print just one line of the entrance UI component
45 screen.append(entrance, 0, entrance.indexOf('\n'));
46 entrance = entrance.substring(entrance.indexOf('\n') + 1);
47 // This will print one row of the dining room
48 screen.append("\t\t").append(PlayerBoardUI.drawDiningRoomRow(p, playerBoard, ctx.getGameMode()));
49 // This will print one teacher per row if present
50 screen.append("\t ").append(PlayerBoardUI.drawTeacher(p, playerBoard, ctx));
51
52 // This will print just one line of the towers UI component
53 screen.append("\t\t ").append(towers, 0, towers.indexOf('\n') + 1);
54 towers = towers.substring(towers.indexOf("\n") + 1);
55 }
56 return screen.toString();
57 }
58
59 /**
60 * It draws a representation of the entrance of the provided player.
61 *
62 * @param pb the {@link PlayerBoard} to which the entrance should be associated with
63 * @param gb reference to the model used to add padding in the entrance when 2 or 4 players are in the game
64 * because they have less students in the entrance than 3 players' game
65 * @return the unused students in a multiline dual column layout String representation
66 */
67 public static String drawEntrance(PlayerBoard pb, Model gb) {
68 String entrance = " "; // the first place is empty because of odd number of students in an even grid
69 int currentEntranceIndex = 0;
70 // Print the content of every place in the entrance
71 for (OptionalValue<PawnColour> p : pb.getEntranceStudents()) {
72 if (p.isPresent())
73 entrance = entrance + Symbols.colorizeBackgroundStudent(p.get(), String.valueOf(currentEntranceIndex)) + " ";
74 else entrance = entrance + " ";
75
76 // Every two students there should be a new line instead of a white space to force the dual column layout
77 if (Symbols.stripFromANSICodes(entrance).length() % 8 == 0) {
78 entrance = entrance.substring(0, entrance.length() - 1); // remove space after pawn in the II column
79 entrance = entrance + "\n";
80 }
81 currentEntranceIndex++;
82 }
83 // Adds padding if not enough students are present to complete the five rows layout
84 if (gb.getMutablePlayerBoards().size() != 3) {
85 entrance = entrance + " " + "\n";
86 }
87 return entrance;
88 }
89
90 /**
91 * It draws a representation of the tower storage of the provided player.
92 *
93 * @param p the {@link PlayerBoard} to which the towers should be associated with
94 * @param gb reference to the model used to check the relationship between towers and player
95 * @return the unused towers in a multiline dual column layout String representation
96 */
97 public static String drawTowers(PlayerBoard p, Model gb) {
98 String towers = "";
99 String towerColour = "";
100 switch (gb.getTeamMapper().getMutableTowerStorage(p).getColour()) {
101 case BLACK -> towerColour = Symbols.BLACK;
102 case GRAY -> towerColour = Symbols.GRAY;
103 case WHITE -> towerColour = Symbols.WHITE;
104 }
105 for (int i = 0; i < 8; i++) {
106 // prints a tower if there is still any to print
107 if (i < gb.getTeamMapper().getMutableTowerStorage(p).getTowerCount()) {
108 towers = towers + Symbols.colour(Symbols.TOWER, towerColour) + " ";
109 } else towers = towers + " "; // adds whitespaces in the remaining empty spaces
110
111 // Every two towers there should be a new line instead of a white space to force the dual column layout
112 if (Symbols.stripFromANSICodes(towers).length() % 4 == 0) {
113 towers = towers.substring(0, towers.length() - 1); // remove space after tower in the II column
114 towers = towers + "\n";
115 }
116 }
117 return towers + "\t\t\n";
118 }
119
120 /**
121 * It draws a dining room's row with its related students and the not yet obtained coins
122 *
123 * @param rowColour the dining room's row which should be printed
124 * @param p the {@link PlayerBoard} to which the dining room should be associated with
125 * @param gameMode reference to the model used to add coin representation if in correct settings
126 * @return a fixed length line containing all the students on the specific dining room's row
127 */
128 public static String drawDiningRoomRow(PawnColour rowColour, PlayerBoard p, GameMode gameMode) {
129 StringBuilder diningRoom = new StringBuilder();
130 // Fills the row with the 10 elements which could be students or empty spaces
131 for (int i = 0; i < 10; i++) {
132 if (i < p.getDiningRoomCount(rowColour)) { // prints a student if there is still any to print
133 diningRoom.append(Symbols.colorizeStudent(rowColour, Symbols.PAWN + " "));
134 } else {
135 // It adds coins in the III, VI and IX positions if the game mode is advanced
136 if (gameMode.equals(GameMode.ADVANCED) && (i + 1) % 3 == 0) {
137 diningRoom.append(Symbols.COIN).append(" ");
138 } else diningRoom.append(" "); // adds whitespaces in the remaining empty places
139 }
140 }
141 return diningRoom.toString();
142 }
143
144 /**
145 * A single teacher will be represented with the standard UI representation of the pawn piece or
146 * an empty space if the player has not conquered that specific teacher yet.
147 *
148 * @param teacher the specific {@link PawnColour} of the teacher to be represented
149 * @param p the {@link PlayerBoard} to which the teacher should be associated with
150 * @param gb reference to the model used to check the relationship between teacher and player
151 * @return single line containing teacher
152 */
153 public static String drawTeacher(PawnColour teacher, PlayerBoard p, Model gb) {
154 if (gb.getOwnTeachers(p).contains(teacher)) {
155 return Symbols.colorizeStudent(teacher, Symbols.PAWN + " ");
156 } else return " ";
157 }
158 }