diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java index fed8a6c..ecd489e 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java @@ -4,37 +4,77 @@ import it.polimi.ingsw.gc14.View.IView; import java.util.List; +/** + * Text-based User Interface (TUI) implementation of {@link IView}. + * + *

Renders the current state of a {@link Game} model directly to the + * standard output using Unicode box-drawing characters and fixed-width + * ASCII tables (see {@link AsciiTable}). + * + *

The display is split into two side-by-side panels: + *

+ * + *

The terminal is cleared before each render via a platform-aware + * {@code cls} / {@code clear} system call. + * + *

Typical usage: + *

{@code
+ * TUI tui = new TUI(game);
+ * tui.setUsername("Alice");
+ * tui.fullRender();
+ * }
+ */ public class TUI implements IView { /** - * The {@link it.polimi.ingsw.gc14.Model.Game } model stored for the game status render. + * The {@link Game} model whose state is rendered. + * Updated via {@link #update(Game)} whenever the game state changes. */ private Game model; /** - * The {@link it.polimi.ingsw.gc14.Model.Player } username stored for the player hand render. + * The username of the local player, used to retrieve and display + * that player's hand in the right panel. + * + * @see #setUsername(String) */ private String username; /** - * Constructor for the class {@code TUI}. - * @param model The model that will be displayed. + * Constructs a {@code TUI} bound to the given game model. + * The username is initialised to an empty string and must be set + * separately via {@link #setUsername(String)} before calling any + * render method that displays the player's hand. + * + * @param model the {@link Game} model to display; must not be {@code null} */ public TUI(Game model) { this.model = model; - this.username=""; + this.username = ""; } /** - * Set the {@code Username} of the player, used for the hand player display. - * @param username + * Sets the username of the local player. + * This value is used by {@link #renderBoard()} and {@link #fullRender()} + * to look up the correct player hand via + * {@link Game#getPlayerByUsername(String)}. + * + * @param username the player's username; must match an existing player + * in the current {@link Game} model */ public void setUsername(String username) { this.username = username; } /** - * Update {@link it.polimi.ingsw.gc14.Model.Game } model stored for the game status render. + * Updates the game model stored in this view. + * Should be called whenever the game state changes so that the next + * render reflects the latest state. + * + * @param model the new {@link Game} model; must not be {@code null} */ @Override public void update(Game model) { @@ -42,119 +82,136 @@ public class TUI implements IView { } /** - * Default method called to display homepage , implements {@link IView}. + * Default render entry point, as required by {@link IView}. + * Delegates to {@link #renderBoard()}. */ - public void render() - { + @Override + public void render() { renderBoard(); } /** - * Method called to display players status and board status. - * In the upper part displays {@link #renderPlayer} information , in a table format. - * In the lower part displays {@link #renderBoard} information in the left , menu options and {@code Username} hand in the right. + * Renders a full view of the game, combining both player status + * and board status. + * + *

Layout: + *

+ * + *

The terminal is cleared before rendering. */ - public void fullRender() - { - try{ - String os = System.getProperty("os.name").toLowerCase(); - ProcessBuilder pb; - if (os.contains("win")) { - pb = new ProcessBuilder("cmd", "/c", "cls"); - } else { - pb = new ProcessBuilder("clear"); - } - pb.inheritIO().start().waitFor(); - } - catch(Exception e){ - } - - Listlines=List.of(model.BoardStamp().split("\n")); - List lines2=List.of((PrintMenuOptions()+"\n"+model.getPlayerByUsername(username)).split("\n")); - System.out.println(model.PlayersStamp()+"\n"+ AsciiTable.sideBySide(lines,lines2,3)); + public void fullRender() { + clearTerminal(); + List lines = List.of(model.BoardStamp().split("\n")); + List lines2 = List.of((printMenuOptions() + "\n" + + model.getPlayerByUsername(username)).split("\n")); + System.out.println(model.PlayersStamp() + "\n" + + AsciiTable.sideBySide(lines, lines2, 3)); } /** - * Method called to display board status. - * Displays turn order ,upper list cards , offer track , lower list cards in the left, menu options and {@code Username} hand in the right. + * Renders the board status only. + * + *

Layout: + *

+ * + *

The terminal is cleared before rendering. */ - public void renderBoard() - { - try{ - String os = System.getProperty("os.name").toLowerCase(); - ProcessBuilder pb; - if (os.contains("win")) { - pb = new ProcessBuilder("cmd", "/c", "cls"); - } else { - pb = new ProcessBuilder("clear"); - } - pb.inheritIO().start().waitFor(); - } - catch(Exception e){ - } - Listlines=List.of(model.BoardStamp().split("\n")); - List lines2=List.of((PrintMenuOptions()+"\nYOUR HAND\n"+model.getPlayerByUsername(username)).split("\n")); - System.out.println(AsciiTable.sideBySide(lines,lines2,3)); - } - /** - * Method called to display player status. - * Displays player prestige value,food value, character deck and building deck , in a table format. - */ - public void renderPlayer() - { - try{ - String os = System.getProperty("os.name").toLowerCase(); - ProcessBuilder pb; - if (os.contains("win")) { - pb = new ProcessBuilder("cmd", "/c", "cls"); - } else { - pb = new ProcessBuilder("clear"); - } - pb.inheritIO().start().waitFor(); - } - catch(Exception e){ - } - Listlines=List.of(model.PlayersStamp().split("\n")); - List lines2=List.of(PrintMenuOptions().split("\n")); - System.out.println(AsciiTable.sideBySide(lines,lines2,3)); + public void renderBoard() { + clearTerminal(); + List lines = List.of(model.BoardStamp().split("\n")); + List lines2 = List.of((printMenuOptions() + "\nYOUR HAND\n" + + model.getPlayerByUsername(username)).split("\n")); + System.out.println(AsciiTable.sideBySide(lines, lines2, 3)); } /** - * Method called to display a message on the terminal. + * Renders the player status table only. + * + *

Layout: + *

+ * + *

The terminal is cleared before rendering. */ - public void showMessage(String message) - { + public void renderPlayer() { + clearTerminal(); + List lines = List.of(model.PlayersStamp().split("\n")); + List lines2 = List.of(printMenuOptions().split("\n")); + System.out.println(AsciiTable.sideBySide(lines, lines2, 3)); + } + + /** + * Prints a plain message to standard output. + * + * @param message the message to display + */ + public void showMessage(String message) { System.out.println(message); } /** - * Method called to display a error on the terminal. + * Prints an error message to standard output. + * + * @param message the error message to display */ - public void showError(String message) - { + public void showError(String message) { + clearTerminal(); + render(); System.out.println(message); } /** - * Method used to set up menu options. - * List of runnable command as a legend. - * @return the string format of the menu options. + * Builds and returns the menu options panel as a two-column + * {@link AsciiTable} with rounded borders. + * + *

The left column lists game action commands (slot choice, draw, pick…), + * the right column lists render shortcuts (full, board, players). + * + * @return the rendered menu table as a multi-line string */ - private String PrintMenuOptions() - { - var table=new AsciiTable(BorderStyle.ROUNDED,2); - table.addHeader( "Menu Options","Render Options"); - table.addRow( List.of("0-SlotChoice(pos)","A-Full Render")); - table.addRow(List.of("1-DrawUpperTribe(pos)","B-Board Render")); - table.addRow(List.of("2-DrawUpperBuilding(pos)","C-Players Render")); - table.addRow(List.of("3-DrawLowerTribe(pos)","")); - table.addRow(List.of("4-DrawLowerBuilding(pos)","")); - table.addRow(List.of("5-PickOptionalTribe(pos)","")); - table.addRow(List.of("6-PickOptionalBuilding(pos)","")); - table.addRow(List.of("7-NoOptional","")); - table.addRow(List.of("8-NoUpperCard","")); - table.addRow(List.of("9-NoLowerCard","")); + private String printMenuOptions() { + var table = new AsciiTable(BorderStyle.ROUNDED, 2); + table.addHeader("Menu Options", "Render Options"); + table.addRow(List.of("0-SlotChoice(pos)", "A-Full Render")); + table.addRow(List.of("1-DrawUpperTribe(pos)", "B-Board Render")); + table.addRow(List.of("2-DrawUpperBuilding(pos)", "C-Players Render")); + table.addRow(List.of("3-DrawLowerTribe(pos)", "")); + table.addRow(List.of("4-DrawLowerBuilding(pos)", "")); + table.addRow(List.of("5-PickOptionalTribe(pos)", "")); + table.addRow(List.of("6-PickOptionalBuilding(pos)", "")); + table.addRow(List.of("7-NoOptional", "")); + table.addRow(List.of("8-NoUpperCard", "")); + table.addRow(List.of("9-NoLowerCard", "")); return table.build(); } -} + /** + * Clears the terminal using a platform-aware system call. + * Uses {@code cls} on Windows and {@code clear} on Unix-like systems. + * Failures are silently ignored to avoid interrupting the render flow. + */ + private void clearTerminal() { + try { + String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb = os.contains("win") + ? new ProcessBuilder("cmd", "/c", "cls") + : new ProcessBuilder("clear"); + pb.inheritIO().start().waitFor(); + } catch (Exception ignored) {} + } +} \ No newline at end of file