refactor: move MapLayout into the game package

The 'map' package held a single class, which breaks the project's own rule in
docs/conventions.md: a subpackage only pays for itself once a class family
reaches three classes and forms its own abstraction.

MapLayout is BFS grid-layout logic and belongs next to Pathfinder in 'game'.
This commit is contained in:
2026-07-14 12:39:15 +02:00
parent 4cf1b42254
commit 1b39eac90e
4 changed files with 21 additions and 4 deletions

View File

@@ -3,9 +3,9 @@ package thb.jeanluc.adventure.command.impl;
import thb.jeanluc.adventure.command.Command; import thb.jeanluc.adventure.command.Command;
import thb.jeanluc.adventure.game.Conditions; import thb.jeanluc.adventure.game.Conditions;
import thb.jeanluc.adventure.game.GameContext; import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.game.MapLayout;
import thb.jeanluc.adventure.game.Light; import thb.jeanluc.adventure.game.Light;
import thb.jeanluc.adventure.game.Pathfinder; import thb.jeanluc.adventure.game.Pathfinder;
import thb.jeanluc.adventure.map.MapLayout;
import thb.jeanluc.adventure.model.Direction; import thb.jeanluc.adventure.model.Direction;
import thb.jeanluc.adventure.model.ExitLock; import thb.jeanluc.adventure.model.ExitLock;
import thb.jeanluc.adventure.model.Room; import thb.jeanluc.adventure.model.Room;

View File

@@ -2,8 +2,8 @@ package thb.jeanluc.adventure.command.impl;
import thb.jeanluc.adventure.command.Command; import thb.jeanluc.adventure.command.Command;
import thb.jeanluc.adventure.game.GameContext; import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.game.MapLayout;
import thb.jeanluc.adventure.io.text.MapView; import thb.jeanluc.adventure.io.text.MapView;
import thb.jeanluc.adventure.map.MapLayout;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package thb.jeanluc.adventure.map; package thb.jeanluc.adventure.game;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import thb.jeanluc.adventure.io.text.CellState; import thb.jeanluc.adventure.io.text.CellState;
@@ -30,6 +30,16 @@ public final class MapLayout {
private MapLayout() { private MapLayout() {
} }
/**
* Builds the map view for the current fog-of-war state. Visited rooms are
* shown by name, their unentered neighbours as unknown cells; rooms beyond
* those are omitted.
*
* @param world the loaded world
* @param visited ids of the rooms the player has entered
* @param current the room the player stands in
* @return the map view; empty if nothing has been visited yet
*/
public static MapView compute(World world, Set<String> visited, Room current) { public static MapView compute(World world, Set<String> visited, Room current) {
if (visited.isEmpty()) { if (visited.isEmpty()) {
return new MapView(List.of(), List.of()); return new MapView(List.of(), List.of());
@@ -101,6 +111,12 @@ public final class MapLayout {
return new MapView(List.copyOf(cells.values()), connections); return new MapView(List.copyOf(cells.values()), connections);
} }
/**
* Assigns grid coordinates to every room reachable from the anchor, which
* sits at the origin. A room reached twice at conflicting coordinates keeps
* its first placement; the world geometry is then not planar and the
* collision is logged.
*/
private static Map<String, int[]> bfs(Room anchor) { private static Map<String, int[]> bfs(Room anchor) {
Map<String, int[]> coords = new HashMap<>(); Map<String, int[]> coords = new HashMap<>();
Deque<Room> queue = new ArrayDeque<>(); Deque<Room> queue = new ArrayDeque<>();
@@ -126,6 +142,7 @@ public final class MapLayout {
return coords; return coords;
} }
/** Grid step for a direction as {@code {dx, dy}}; y grows southwards. */
private static int[] delta(Direction d) { private static int[] delta(Direction d) {
return switch (d) { return switch (d) {
case NORTH -> new int[]{0, -1}; case NORTH -> new int[]{0, -1};

View File

@@ -1,4 +1,4 @@
package thb.jeanluc.adventure.map; package thb.jeanluc.adventure.game;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.io.text.CellState; import thb.jeanluc.adventure.io.text.CellState;