Add: ASCII Builder

This commit is contained in:
rubenpirreram
2026-04-25 16:24:03 +02:00
parent de4738beba
commit d69a806b3d
3 changed files with 180 additions and 0 deletions
@@ -0,0 +1,48 @@
package it.polimi.ingsw.gc14.View.TUI;
import java.util.*;
// Helper generale per costruire tabelle ASCII
public class AsciiTable {
private final BorderStyle s;
private final int cols, colWidth;
private final List<List<String>> rows = new ArrayList<>();
private final List<Integer> separators = new ArrayList<>();
public AsciiTable(BorderStyle s, int cols, int colWidth) {
this.s = s; this.cols = cols; this.colWidth = colWidth;
}
public void addRow(String... cells) { rows.add(Arrays.asList(cells)); }
public void addRow(List<String> cells) { rows.add(cells); }
public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); }
public void addSeparator() { separators.add(rows.size()); }
public String build() {
var sb = new StringBuilder();
sb.append(hline(s.tl(), s.mt(), s.tr())).append('\n');
for (int i = 0; i < rows.size(); i++) {
sb.append(s.v());
for (String cell : rows.get(i))
sb.append(rpad(" " + cell, colWidth)).append(s.v());
sb.append('\n');
if (separators.contains(i) && i < rows.size() - 1)
sb.append(hline(s.sl(), s.sx(), s.sr())).append('\n');
}
sb.append(hline(s.bl(), s.mb(), s.br()));
return sb.toString();
}
private String hline(String l, String m, String r) {
var sb = new StringBuilder(l);
for (int i = 0; i < cols; i++) {
sb.append(s.h().repeat(colWidth));
if (i < cols - 1) sb.append(m);
}
return sb.append(r).toString();
}
private String rpad(String s, int w) {
if (s.length() >= w) return s.substring(0, w);
return s + " ".repeat(w - s.length());
}
}
@@ -0,0 +1,39 @@
package it.polimi.ingsw.gc14.View.TUI;
public enum BorderStyle {
UNICODE("","","","","","","","","","","","","","",""),
ASCII ("+","+","+","+","-","|","+","+","+","+","+","+","+","-","+"),
ROUNDED("","","","","","","","","","","","","","","");
private final String tl,tr,bl,br,h,v,ml,mr,mt,mb,x,sl,sr,sh,sx;
BorderStyle(String tl,String tr,String bl,String br,
String h, String v, String ml,String mr,
String mt,String mb,String x,
String sl,String sr,String sh,String sx) {
this.tl = tl; this.tr = tr;
this.bl = bl; this.br = br;
this.h = h; this.v = v;
this.ml = ml; this.mr = mr;
this.mt = mt; this.mb = mb;
this.x = x;
this.sl = sl; this.sr = sr;
this.sh = sh; this.sx = sx;
}
public String tl() { return tl; }
public String tr() { return tr; }
public String bl() { return bl; }
public String br() { return br; }
public String h() { return h; }
public String v() { return v; }
public String ml() { return ml; }
public String mr() { return mr; }
public String mt() { return mt; }
public String mb() { return mb; }
public String x() { return x; }
public String sl() { return sl; }
public String sr() { return sr; }
public String sh() { return sh; }
public String sx() { return sx; }
}
@@ -0,0 +1,93 @@
package it.polimi.ingsw.gc14.View.TUI;
import it.polimi.ingsw.gc14.Model.Game;
public class TUI {
// ── dati di stato ───────────────────────────────────────────
private BorderStyle style = BorderStyle.UNICODE;
private Game model;
// ── punto di ingresso ───────────────────────────────────────
public String render() {
var sb = new StringBuilder();
sb.append(renderHeader());
sb.append(renderTurnOrder());
sb.append(renderOfferTrack());
sb.append(renderCardRows());
sb.append(renderTableaux());
sb.append(renderFooter());
return sb.toString();
}
// ── sezioni ─────────────────────────────────────────────────
private String renderTurnOrder() {
var table = new AsciiTable(style, 4, 10); // 4 colonne, largh 10
table.addRow(model.getPlayers().stream()
.map(p -> + ". " + p.getUserName())
.toList());
table.addRow(state.getPlayers().stream()
.map(p -> p.getTotemPosition() != null
? "totem: " + p.getTotemPosition()
: "(da piaz)")
.toList());
return " TURN ORDER\n" + table.build() + "\n";
}
private String renderOfferTrack() {
var table = new AsciiTable(style, 5, 14);
table.addRow(state.getOfferTiles().stream()
.map(t -> t.getId() + ": " + t.getLabel()).toList());
table.addRow(state.getOfferTiles().stream()
.map(OfferTile::getRowsLabel).toList());
table.addRow(state.getOfferTiles().stream()
.map(t -> state.getTotemOnTile(t.getId())).toList());
return " OFFER TRACK\n" + table.build() + "\n";
}
private String renderCardRows() {
int cols = state.getTopRow().size();
var table = new AsciiTable(style, cols, 13);
table.addRow(state.getTopRow().stream()
.map(c -> "[" + c.getTypeLabel() + "]").toList());
table.addRow(state.getTopRow().stream()
.map(Card::getName).toList());
table.addSeparator();
table.addRow(state.getBotRow().stream()
.map(c -> "[" + c.getTypeLabel() + "]").toList());
table.addRow(state.getBotRow().stream()
.map(Card::getName).toList());
return " CARTE IN GIOCO\n" + prefix("TOP ", "BOT ", table.build()) + "\n";
}
private String renderTableaux() {
var sb = new StringBuilder(" TABLEAU GIOCATORI\n\n");
for (Player p : state.getPlayers()) {
String marker = p.isActive() ? ">>>" : " ";
sb.append(String.format(" %s %s%s Food:%d PP:%d%n",
marker, p.getName(),
p.isActive() ? " [TUO TURNO]" : "",
p.getFood(), p.getPP()));
sb.append(renderPlayerTableau(p));
sb.append("\n");
}
return sb.toString();
}
private String renderPlayerTableau(Player p) {
var table = new AsciiTable(style, 3, 14);
table.addHeader("PERSONAGGI", "EDIFICI", "RISORSE");
int rows = Math.max(p.getChars().size(),
Math.max(p.getBuildings().size(), 3));
for (int i = 0; i < rows; i++) {
String ch = i < p.getChars().size() ? p.getChars().get(i) : "";
String bd = i < p.getBuildings().size() ? p.getBuildings().get(i) : "";
String rs = switch (i) {
case 0 -> "Food: " + "O".repeat(p.getFood());
case 1 -> "PP: " + p.getPP();
case 2 -> "Chars:" + p.getChars().size() + " Edif:" + p.getBuildings().size();
default -> "";
};
table.addRow(ch, bd, rs);
}
return " " + table.build().replace("\n", "\n ");
}
}