diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java index 8aa08a3..817b772 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java @@ -10,6 +10,7 @@ import thb.jeanluc.adventure.command.impl.GoCommand; import thb.jeanluc.adventure.command.impl.HelpCommand; import thb.jeanluc.adventure.command.impl.InventoryCommand; import thb.jeanluc.adventure.command.impl.LookCommand; +import thb.jeanluc.adventure.command.impl.MapCommand; import thb.jeanluc.adventure.command.impl.QuitCommand; import thb.jeanluc.adventure.command.impl.ReadCommand; import thb.jeanluc.adventure.command.impl.TakeCommand; @@ -68,6 +69,7 @@ public final class App { registry.register(new UseCommand(), "use"); registry.register(new ReadCommand(), "read"); registry.register(new ExamineCommand(), "examine", "x", "inspect"); + registry.register(new MapCommand(), "map", "m"); registry.register(new TalkCommand(), "talk", "speak"); registry.register(new GiveCommand(), "give"); registry.register(new HelpCommand(registry), "help", "?"); diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/command/impl/MapCommand.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/command/impl/MapCommand.java new file mode 100644 index 0000000..d73be6a --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/command/impl/MapCommand.java @@ -0,0 +1,26 @@ +package thb.jeanluc.adventure.command.impl; + +import thb.jeanluc.adventure.command.Command; +import thb.jeanluc.adventure.game.GameContext; +import thb.jeanluc.adventure.io.text.MapView; +import thb.jeanluc.adventure.map.MapLayout; + +import java.util.List; + +/** Shows the fog-of-war map of explored rooms. Usage: {@code map}. */ +public class MapCommand implements Command { + + @Override + public void execute(GameContext ctx, List args) { + MapView view = MapLayout.compute( + ctx.getWorld(), + ctx.getPlayer().getVisitedRoomIds(), + ctx.getPlayer().getCurrentRoom()); + ctx.getIo().showMap(view); + } + + @Override + public String help() { + return "map - show the map of explored rooms"; + } +} diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java index d88cb7c..8be6545 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java @@ -1,6 +1,8 @@ package thb.jeanluc.adventure.io; +import thb.jeanluc.adventure.io.text.AsciiMap; import thb.jeanluc.adventure.io.text.Hud; +import thb.jeanluc.adventure.io.text.MapView; import thb.jeanluc.adventure.io.text.RoomView; import thb.jeanluc.adventure.io.text.Span; import thb.jeanluc.adventure.io.text.Style; @@ -100,6 +102,11 @@ public class ConsoleIO implements GameIO { out.println(paint(Style.DIM, line)); } + @Override + public void showMap(MapView view) { + print(AsciiMap.render(view, glyphs != GlyphMode.ASCII)); + } + private String section(String label, List xs, Style st) { StringBuilder sb = new StringBuilder(" ").append(paint(Style.DIM, label)).append(" "); for (int i = 0; i < xs.size(); i++) { diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/GameIO.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/GameIO.java index 3af5b09..060d88d 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/GameIO.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/GameIO.java @@ -1,6 +1,8 @@ package thb.jeanluc.adventure.io; +import thb.jeanluc.adventure.io.text.AsciiMap; import thb.jeanluc.adventure.io.text.Hud; +import thb.jeanluc.adventure.io.text.MapView; import thb.jeanluc.adventure.io.text.Renderings; import thb.jeanluc.adventure.io.text.RoomView; import thb.jeanluc.adventure.io.text.StyledText; @@ -32,4 +34,14 @@ public interface GameIO { default void setHud(Hud hud) { // no-op } + + /** Per-turn push of the current map. GUI repaints its panel; console ignores. */ + default void setMap(MapView view) { + // no-op + } + + /** On-demand map (the 'map' command). Default renders ASCII (Unicode frames). */ + default void showMap(MapView view) { + print(AsciiMap.render(view, true)); + } } diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/command/impl/MapCommandTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/command/impl/MapCommandTest.java new file mode 100644 index 0000000..1382076 --- /dev/null +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/command/impl/MapCommandTest.java @@ -0,0 +1,40 @@ +package thb.jeanluc.adventure.command.impl; + +import org.junit.jupiter.api.Test; +import thb.jeanluc.adventure.game.GameContext; +import thb.jeanluc.adventure.io.TestIO; +import thb.jeanluc.adventure.model.Direction; +import thb.jeanluc.adventure.model.Player; +import thb.jeanluc.adventure.model.Room; +import thb.jeanluc.adventure.model.World; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +class MapCommandTest { + + @Test + void map_showsVisitedRoomAndKnownNeighbour() { + Room kitchen = new Room("kitchen", "Kitchen", "d"); + Room hallway = new Room("hallway", "Hallway", "d"); + kitchen.addExit(Direction.NORTH, hallway); + hallway.addExit(Direction.SOUTH, kitchen); + Map rooms = new LinkedHashMap<>(); + rooms.put("kitchen", kitchen); + rooms.put("hallway", hallway); + World world = new World(rooms, Map.of(), Map.of(), "t", "w"); + + Player player = new Player(kitchen, 0); // visited = {kitchen}; hallway is a KNOWN stub + TestIO io = new TestIO(); + GameContext ctx = new GameContext(world, player, io); + + new MapCommand().execute(ctx, List.of()); + + String out = io.allOutput(); + assertThat(out).contains("Kitchen"); // current room name appears on the map + assertThat(out).contains("?"); // unexplored neighbour stub + } +}