From 650bbbe58c32995333d8a611bbfad1d077082acd Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sun, 31 May 2026 20:22:59 +0200 Subject: [PATCH] feat(io): welcome banner for game start Co-Authored-By: Claude Opus 4.8 (1M context) --- .../main/java/thb/jeanluc/adventure/App.java | 3 ++- .../thb/jeanluc/adventure/io/text/Banner.java | 18 ++++++++++++++++++ .../jeanluc/adventure/io/text/BannerTest.java | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Banner.java create mode 100644 Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/BannerTest.java diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java index 8b74bfb..8aa08a3 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java @@ -19,6 +19,7 @@ import thb.jeanluc.adventure.game.Game; import thb.jeanluc.adventure.game.GameContext; import thb.jeanluc.adventure.io.ConsoleIO; import thb.jeanluc.adventure.io.GameIO; +import thb.jeanluc.adventure.io.text.Banner; import thb.jeanluc.adventure.loader.WorldLoader; /** @@ -77,7 +78,7 @@ public final class App { Game game = new Game(ctx, registry, new CommandParser()); quit.bind(game); - io.write(loaded.world().getTitle()); + io.print(Banner.welcome(loaded.world().getTitle())); io.write(loaded.world().getWelcomeMessage()); new LookCommand().execute(ctx, java.util.List.of()); diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Banner.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Banner.java new file mode 100644 index 0000000..f491446 --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/text/Banner.java @@ -0,0 +1,18 @@ +package thb.jeanluc.adventure.io.text; + +/** Builds styled banners for big moments (game start, finale). */ +public final class Banner { + + private Banner() { + } + + /** A framed, heading-styled welcome banner for the given title. */ + public static StyledText welcome(String title) { + String bar = "=".repeat(Math.max(8, title.length() + 8)); + return StyledText.builder() + .heading(bar + "\n") + .heading(" " + title + "\n") + .heading(bar) + .build(); + } +} diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/BannerTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/BannerTest.java new file mode 100644 index 0000000..8c89430 --- /dev/null +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/text/BannerTest.java @@ -0,0 +1,15 @@ +package thb.jeanluc.adventure.io.text; + +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + +class BannerTest { + + @Test + void welcome_containsTitleAsHeading() { + StyledText b = Banner.welcome("Haunted Manor"); + assertThat(b.plainText()).contains("Haunted Manor"); + boolean hasHeading = b.spans().stream().anyMatch(s -> s.style() == Style.HEADING); + assertThat(hasHeading).isTrue(); + } +}