semesterprojekt: implement full text adventure (phases 1-7)
Walking skeleton through Swing GUI: YAML-driven world (4 rooms, 4 items, 1 NPC), HashMap command dispatch with parser, three-tier item hierarchy (readable / switchable / plain), and end-to-end NPC give/receive flow. 67 tests green.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package thb.jeanluc.adventure.game;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import thb.jeanluc.adventure.command.Command;
|
||||
import thb.jeanluc.adventure.command.CommandParser;
|
||||
import thb.jeanluc.adventure.command.CommandRegistry;
|
||||
import thb.jeanluc.adventure.command.ParsedCommand;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* The main game loop. Reads a line, parses it, dispatches the matching
|
||||
* command, and writes the result — until {@link #stop()} flips the
|
||||
* {@link #running} flag (typically by the quit command or EOF on input).
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class Game {
|
||||
|
||||
/** Game context shared with every command. */
|
||||
private final GameContext ctx;
|
||||
|
||||
/** Command lookup table. */
|
||||
private final CommandRegistry registry;
|
||||
|
||||
/** Tokenising parser for player input. */
|
||||
private final CommandParser parser;
|
||||
|
||||
/** Loop flag. Flipped to false by {@link #stop()}. */
|
||||
private boolean running = true;
|
||||
|
||||
/**
|
||||
* Runs the loop until {@link #stop()} is called or input is exhausted.
|
||||
*/
|
||||
public void run() {
|
||||
while (running) {
|
||||
String input = ctx.getIo().readLine();
|
||||
if (input == null) {
|
||||
break;
|
||||
}
|
||||
ParsedCommand parsed = parser.parse(input);
|
||||
if (parsed.verb().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Optional<Command> cmd = registry.find(parsed.verb());
|
||||
if (cmd.isEmpty()) {
|
||||
ctx.getIo().write("I don't understand '" + parsed.verb() + "'. Type 'help'.");
|
||||
} else {
|
||||
cmd.get().execute(ctx, parsed.args());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the loop to terminate after the current iteration.
|
||||
*/
|
||||
public void stop() {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package thb.jeanluc.adventure.game;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import thb.jeanluc.adventure.io.GameIO;
|
||||
import thb.jeanluc.adventure.model.Player;
|
||||
import thb.jeanluc.adventure.model.World;
|
||||
|
||||
/**
|
||||
* Bundle of everything a command needs to do its work: the world, the
|
||||
* player, and the IO channel. Passing this single object keeps command
|
||||
* signatures small and consistent.
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class GameContext {
|
||||
|
||||
/** Loaded world (rooms, items, npcs). */
|
||||
private final World world;
|
||||
|
||||
/** The player avatar. */
|
||||
private final Player player;
|
||||
|
||||
/** IO channel for reading input and writing output. */
|
||||
private final GameIO io;
|
||||
}
|
||||
Reference in New Issue
Block a user