From 5ebbd2ce42e5333f1600f3b1e9cb4eed033933b2 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sun, 31 May 2026 21:09:08 +0200 Subject: [PATCH] feat(io): adaptive ASCII map width; document map command, mark sub-project done AsciiMap sizes room boxes to the longest visible name (capped) so names like 'Dark Hallway' are no longer truncated; connector centering follows. Co-Authored-By: Claude Opus 4.8 (1M context) --- Semesterprojekt/README.md | 1 + Semesterprojekt/docs/enhancement-ideas.md | 9 +++++- .../jeanluc/adventure/io/text/AsciiMap.java | 29 ++++++++++++------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Semesterprojekt/README.md b/Semesterprojekt/README.md index 9125ad6..0806541 100644 --- a/Semesterprojekt/README.md +++ b/Semesterprojekt/README.md @@ -46,6 +46,7 @@ mvn exec:java@gui # Swing-GUI (thb.jeanluc.adventure.AppGui) |---|---|---| | `go ` | `move`, `walk` | In eine Himmelsrichtung gehen | | `look` | `l` | Aktuellen Raum beschreiben | +| `map` | `m` | Karte der erkundeten Räume anzeigen | | `inventory` | `inv`, `i` | Inventar anzeigen | | `take ` | `pick`, `get` | Gegenstand aufnehmen | | `drop ` | `put` | Gegenstand ablegen | diff --git a/Semesterprojekt/docs/enhancement-ideas.md b/Semesterprojekt/docs/enhancement-ideas.md index ee69844..900a459 100644 --- a/Semesterprojekt/docs/enhancement-ideas.md +++ b/Semesterprojekt/docs/enhancement-ideas.md @@ -56,7 +56,14 @@ Farb-Rollen: Items / NPCs / Exits / Heading / Gefahr. - **Konsole**: Font nicht kontrollierbar → gestufte Fallbacks (reines ASCII → Unicode-Box-Drawing → Nerd-Glyphen) statt harter Annahme. -### 3. Karte / Map +### 3. Karte / Map ✅ umgesetzt (Branch `feature/map`) + +> Umgesetzt: `MapLayout` (BFS-Gitter-Layout + Fog of War), `MapView`-Modell, +> GUI-`MapPanel` (Graphics2D, ersetzt die Exit-Liste), Konsolen-ASCII via +> `AsciiMap` + `map`-Befehl, Besuchte-Räume-Tracking auf `Player`, Map-Push pro Zug. +> Item/NPC-Marker und Türen-Styling offen (Quest-Teilprojekt). Spec/Plan unter +> `docs/superpowers/`. + - Übersichtskarte der Räume – in **beiden** Modi. - Konsole: ASCII-Map. GUI: gezeichnete Map (Grid/Graph). diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/AsciiMap.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/AsciiMap.java index 02b728c..a6bd119 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/AsciiMap.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/AsciiMap.java @@ -11,8 +11,9 @@ import java.util.Set; */ public final class AsciiMap { - private static final int INNER = 7; // room name field width - private static final int GAP = 3; // horizontal corridor width + private static final int MIN_INNER = 7; // minimum room name field width + private static final int MAX_INNER = 14; // cap so the map stays compact + private static final int GAP = 3; // horizontal corridor width private AsciiMap() { } @@ -24,10 +25,12 @@ public final class AsciiMap { int maxX = 0; int maxY = 0; + int inner = MIN_INNER; Map at = new HashMap<>(); for (RoomCell c : view.cells()) { maxX = Math.max(maxX, c.x()); maxY = Math.max(maxY, c.y()); + inner = Math.max(inner, Math.min(MAX_INNER, c.name().length())); at.put(key(c.x(), c.y()), c); } @@ -50,19 +53,23 @@ public final class AsciiMap { String hz = unicode ? "─" : "-"; String vt = unicode ? "│" : "|"; + int boxW = inner + 2; + int leftPad = (boxW - 1) / 2; + int rightPad = boxW - 1 - leftPad; + StyledText.Builder b = StyledText.builder(); for (int gy = 0; gy <= maxY; gy++) { for (int line = 0; line < 3; line++) { for (int gx = 0; gx <= maxX; gx++) { RoomCell c = at.get(key(gx, gy)); if (c == null) { - b.plain(" ".repeat(INNER + 2)); + b.plain(" ".repeat(boxW)); } else if (line == 0) { - styled(b, tl + hz.repeat(INNER) + tr, c.state()); + styled(b, tl + hz.repeat(inner) + tr, c.state()); } else if (line == 2) { - styled(b, bl + hz.repeat(INNER) + br, c.state()); + styled(b, bl + hz.repeat(inner) + br, c.state()); } else { - styled(b, vt + center(label(c), INNER) + vt, c.state()); + styled(b, vt + center(label(c, inner), inner) + vt, c.state()); } if (gx < maxX) { if (line == 1 && hEdge.contains(key(gx, gy))) { @@ -77,9 +84,9 @@ public final class AsciiMap { if (gy < maxY) { for (int gx = 0; gx <= maxX; gx++) { if (vEdge.contains(key(gx, gy))) { - b.plain(" ".repeat(4)).dim(vt).plain(" ".repeat(4)); + b.plain(" ".repeat(leftPad)).dim(vt).plain(" ".repeat(rightPad)); } else { - b.plain(" ".repeat(INNER + 2)); + b.plain(" ".repeat(boxW)); } if (gx < maxX) { b.plain(" ".repeat(GAP)); @@ -99,10 +106,10 @@ public final class AsciiMap { } } - private static String label(RoomCell c) { + private static String label(RoomCell c, int inner) { String n = c.name(); - if (n.length() > INNER) { - n = n.substring(0, INNER); + if (n.length() > inner) { + n = n.substring(0, inner); } return n; }