diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Hud.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Hud.java new file mode 100644 index 0000000..f4a1e7d --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Hud.java @@ -0,0 +1,4 @@ +package thb.jeanluc.adventure.io.text; + +/** Status snapshot for the HUD region. */ +public record Hud(String location, int gold, int turn, boolean lightOn) {} diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Renderings.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Renderings.java new file mode 100644 index 0000000..9baf1aa --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Renderings.java @@ -0,0 +1,49 @@ +package thb.jeanluc.adventure.io.text; + +import java.util.List; + +/** Default, layout-free rendering of high-level views into {@link StyledText}. */ +public final class Renderings { + + private Renderings() { + } + + /** Generic room rendering used by non-overriding {@code GameIO}s (e.g. tests). */ + public static StyledText roomToStyledText(RoomView r) { + StyledText.Builder b = StyledText.builder(); + b.heading(r.name()).plain("\n"); + b.plain(r.description().stripTrailing()); + if (!r.items().isEmpty()) { + b.plain("\nYou see: "); + appendList(b, r.items(), Style.ITEM); + b.plain("."); + } + if (!r.npcs().isEmpty()) { + b.plain("\nHere is: "); + appendList(b, r.npcs(), Style.NPC); + b.plain("."); + } + if (r.exits().isEmpty()) { + b.plain("\nThere are no obvious exits."); + } else { + b.plain("\nExits: "); + appendList(b, r.exits(), Style.EXIT); + b.plain("."); + } + return b.build(); + } + + private static void appendList(StyledText.Builder b, List xs, Style st) { + for (int i = 0; i < xs.size(); i++) { + if (i > 0) { + b.plain(", "); + } + switch (st) { + case ITEM -> b.item(xs.get(i)); + case NPC -> b.npc(xs.get(i)); + case EXIT -> b.exit(xs.get(i)); + default -> b.plain(xs.get(i)); + } + } + } +} diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/RoomView.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/RoomView.java new file mode 100644 index 0000000..9b77854 --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/RoomView.java @@ -0,0 +1,13 @@ +package thb.jeanluc.adventure.io.text; + +import java.util.List; + +/** Semantic snapshot of a room for rendering. Display-ready strings, no layout. */ +public record RoomView(String name, String description, + List items, List npcs, List exits) { + public RoomView { + items = List.copyOf(items); + npcs = List.copyOf(npcs); + exits = List.copyOf(exits); + } +} diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/RenderingsTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/RenderingsTest.java new file mode 100644 index 0000000..d13fab1 --- /dev/null +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/RenderingsTest.java @@ -0,0 +1,38 @@ +package thb.jeanluc.adventure.io.text; + +import org.junit.jupiter.api.Test; +import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; + +class RenderingsTest { + + @Test + void roomToStyledText_includesNameDescriptionItemsNpcsExits() { + RoomView room = new RoomView("Kitchen", "A cold kitchen.", + List.of("Lamp", "Letter"), List.of("Old Man"), List.of("north", "east")); + + String text = Renderings.roomToStyledText(room).plainText(); + + assertThat(text).contains("Kitchen"); + assertThat(text).contains("A cold kitchen."); + assertThat(text).contains("Lamp").contains("Letter"); + assertThat(text).contains("Old Man"); + assertThat(text).contains("north").contains("east"); + } + + @Test + void roomToStyledText_noExits_saysNoObviousExits() { + RoomView room = new RoomView("Void", "Nothing.", List.of(), List.of(), List.of()); + assertThat(Renderings.roomToStyledText(room).plainText()) + .contains("no obvious exits"); + } + + @Test + void roomToStyledText_tagsItemSpansWithItemStyle() { + RoomView room = new RoomView("Kitchen", "desc", + List.of("Lamp"), List.of(), List.of("north")); + boolean hasItemSpan = Renderings.roomToStyledText(room).spans().stream() + .anyMatch(s -> s.style() == Style.ITEM && s.text().equals("Lamp")); + assertThat(hasItemSpan).isTrue(); + } +}