Removed ZorkMap

This commit is contained in:
Claudio Maggioni 2022-11-22 18:31:06 +01:00
parent 5786e58842
commit 4c70ba2800
23 changed files with 319 additions and 334 deletions

View File

@ -1,12 +1,5 @@
package com.github.dtschust.zork;
import com.github.dtschust.zork.objects.ZorkContainer;
import com.github.dtschust.zork.objects.ZorkRoom;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.CONTAINER;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.ROOM;
/* Has conditions*/
public class ZorkConditionHas extends ZorkCondition {
private final String has;
@ -20,25 +13,13 @@ public class ZorkConditionHas extends ZorkCondition {
@Override
public boolean evaluate(ZorkGame game) {
/*Inventory is a special case as it isn't the name of any object in the game, check for it specifically*/
// Inventory is a special case as it isn't the name of any object in the game, check for it specifically
if (owner.equals("inventory")) {
return evaluateCondition(game.inventory.contains(object));
} else {
/* is it a room?*/
ZorkRoom roomObject = (ZorkRoom) game.get(ROOM, owner);
if (roomObject != null) {
return evaluateCondition(roomObject.getItem().contains(object));
}
/* is it a container?*/
else {
ZorkContainer containerObject = (ZorkContainer) game.get(CONTAINER, owner);
if (containerObject != null) {
return evaluateCondition(containerObject.containsItem(object));
}
}
return game.getRoom(owner).map(r -> evaluateCondition(r.containsItem(object))).orElseGet(() ->
game.getContainer(owner).map(c -> evaluateCondition(c.containsItem(object))).orElse(false));
}
return false;
}
private boolean evaluateCondition(boolean contained) {

View File

@ -1,19 +1,16 @@
package com.github.dtschust.zork;
import com.github.dtschust.zork.objects.ZorkObject;
/* Status conditions*/
public class ZorkConditionStatus extends ZorkCondition {
private final String status;
public ZorkConditionStatus(String status, String object) {
public ZorkConditionStatus(final String status, final String object) {
super(object);
this.status = status;
}
@Override
public boolean evaluate(ZorkGame game) {
ZorkObject tested = game.getListThroughLookup(ZorkObject.class, object).get(object);
return tested != null && tested.isStatusEqualTo(status);
public boolean evaluate(final ZorkGame game) {
return game.getObject(object).map(o -> o.isStatusEqualTo(status)).orElse(false);
}
}

View File

@ -1,38 +1,44 @@
package com.github.dtschust.zork;
import com.github.dtschust.zork.objects.*;
import com.github.dtschust.zork.types.ZorkMap;
import com.github.dtschust.zork.types.ObjectCollector;
import com.github.dtschust.zork.types.ZorkMapByName;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.ITEM;
import java.util.*;
import java.util.stream.Stream;
public class ZorkGame {
public final PrintStream stream;
public final Set<String> inventory = new HashSet<>();
private final ZorkMap<ZorkRoom> rooms = new ZorkMap<>();
private final ZorkMap<ZorkItem> items = new ZorkMap<>();
private final ZorkMap<ZorkContainer> containers = new ZorkMap<>();
private final ZorkMap<ZorkCreature> creatures = new ZorkMap<>();
private final HashMap<String, ZorkObjectTypes> objectLookup = new HashMap<>();
private final ZorkMapByName<ZorkRoom> rooms;
private final ZorkMapByName<ZorkItem> items;
private final ZorkMapByName<ZorkContainer> containers;
private final ZorkMapByName<ZorkCreature> creatures;
private boolean running = false;
private String currentRoom;
public ZorkGame(PrintStream stream) {
public ZorkGame(final Collection<ZorkRoom> rooms,
final Collection<ZorkItem> items,
final Collection<ZorkContainer> containers,
final Collection<ZorkCreature> creatures,
final PrintStream stream) {
this.stream = stream;
this.rooms = new ZorkMapByName<>(rooms);
this.items = new ZorkMapByName<>(items);
this.containers = new ZorkMapByName<>(containers);
this.creatures = new ZorkMapByName<>(creatures);
}
public ZorkRoom getCurrentRoom() {
return rooms.get(currentRoom);
return rooms.get(currentRoom).orElseThrow(() ->
new IllegalStateException("current room not found: " + currentRoom));
}
public boolean changeRoom(String newRoom) {
if (rooms.containsKey(newRoom)) {
if (rooms.containsName(newRoom)) {
currentRoom = newRoom;
running = true;
return true;
@ -48,75 +54,73 @@ public class ZorkGame {
running = false;
}
public ZorkObjectTypes getTypeFromLookup(String object) {
return objectLookup.get(object);
public void removeFromBorders(final ZorkRoom room) {
for (final ZorkRoom bordering : rooms.values()) {
bordering.removeBorderingRoom(room.getName());
}
rooms.put(room);
}
public void addObjectThroughLookup(ZorkObjectTypes type, ZorkObject object) {
putInMapGivenType(type, object);
objectLookup.put(object.getName(), type);
}
public <T extends ZorkObject> ZorkMap<T> getListThroughLookup(Class<T> cast, String name) {
return values(cast, objectLookup.get(name));
}
public <T extends ZorkObject> ZorkMap<T> values(Class<T> cast, ZorkObjectTypes type) {
return (ZorkMap<T>) getMapFromType(type);
}
public ZorkObject get(ZorkObjectTypes type, String key) {
return getMapFromType(type).get(key);
}
public void put(ZorkObjectTypes type, ZorkObject object) {
putInMapGivenType(type, object);
}
private ZorkMap<? extends ZorkObject> getMapFromType(ZorkObjectTypes type) {
switch (type) {
case ROOM:
return rooms;
case CONTAINER:
return containers;
case CREATURE:
return creatures;
case ITEM:
return items;
default:
throw new IllegalStateException("Unexpected value: " + type);
public void updateObjectStatus(final String objectName, final String status) {
for (final ZorkMapByName<? extends ZorkObject> map : List.of(containers, rooms, items, creatures)) {
final Optional<? extends ZorkObject> o = map.get(objectName);
if (o.isPresent()) {
o.get().updateStatus(status);
break;
}
}
}
private void putInMapGivenType(ZorkObjectTypes type, ZorkObject object) {
switch (type) {
case ROOM:
rooms.put((ZorkRoom) object);
break;
case CONTAINER:
containers.put((ZorkContainer) object);
break;
case CREATURE:
creatures.put((ZorkCreature) object);
break;
case ITEM:
items.put((ZorkItem) object);
break;
default:
throw new IllegalStateException("Unexpected value: " + type);
public Optional<? extends ZorkObject> getObject(final String objectName) {
return Stream.of(containers, rooms, items, creatures)
.map(m -> m.get(objectName))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
}
public void addObjectToCollection(final ZorkObject object, final String destinationName) {
for (final ZorkMapByName<? extends ObjectCollector> map : List.of(containers, rooms)) {
final Optional<? extends ObjectCollector> o = map.get(destinationName);
if (o.isPresent()) {
o.get().addObject(object);
return;
}
}
throw new UnsupportedOperationException("destination " + destinationName + " not a room or container");
}
public void removeObjectFromCollections(final ZorkObject object) {
for (final ZorkMapByName<? extends ObjectCollector> map : List.of(containers, rooms)) {
for (ObjectCollector v : map.values()) {
v.removeObject(object);
}
}
}
private boolean evaluateTriggers(final ZorkGame game, final String currentCommand) {
final boolean currentRoom = getCurrentRoom().evaluateTriggers(game, currentCommand);
final boolean itemsInInventory = ZorkTrigger.evaluateTriggerCollection(inventory, ITEM, game, currentCommand);
public Optional<ZorkRoom> getRoom(final String roomName) {
return this.rooms.get(roomName);
}
return currentRoom || itemsInInventory;
public Optional<ZorkCreature> getCreature(final String creatureName) {
return this.creatures.get(creatureName);
}
public Optional<ZorkItem> getItem(final String itemName) {
return this.items.get(itemName);
}
public Optional<ZorkContainer> getContainer(final String containerName) {
return this.containers.get(containerName);
}
public boolean evaluateTriggers(final String currentCommand) {
return evaluateTriggers(this, currentCommand);
final boolean currentRoom1 = getCurrentRoom().evaluateTriggers(this, currentCommand);
final boolean itemsInInventory = ZorkTrigger.evaluateTriggersFor(inventory.stream(), this, currentCommand);
return currentRoom1 || itemsInInventory;
}
}

View File

@ -1,11 +1,12 @@
package com.github.dtschust.zork;
import com.github.dtschust.zork.objects.ZorkObjectTypes;
import com.github.dtschust.zork.types.HasPrintsAndActions;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class ZorkTrigger implements HasPrintsAndActions {
@ -29,13 +30,15 @@ public class ZorkTrigger implements HasPrintsAndActions {
this.type = type;
}
public static boolean evaluateTriggerCollection(final Collection<String> collection,
final ZorkObjectTypes type,
final ZorkGame game,
final String input) {
public static boolean evaluateTriggersFor(final Stream<String> collection,
final ZorkGame game,
final String input) {
// non short-circuited to execute all side effects of evaluateTriggers
return collection.stream()
.map(i -> game.get(type, i).evaluateTriggers(game, input))
return collection
.map(game::getObject)
.filter(Optional::isPresent)
.map(Optional::get)
.map(a -> a.evaluateTriggers(game, input))
.reduce(false, (a, b) -> a || b);
}

View File

@ -1,14 +1,14 @@
package com.github.dtschust.zork.objects;
import com.github.dtschust.zork.ZorkTrigger;
import com.github.dtschust.zork.types.HasSetOfCollectable;
import com.github.dtschust.zork.types.ObjectCollector;
import java.util.*;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.ITEM;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/* Container*/
public class ZorkContainer extends ZorkObject implements HasSetOfCollectable {
public class ZorkContainer extends ZorkObject implements ObjectCollector {
private final Set<String> items;
private boolean open;
@ -52,11 +52,21 @@ public class ZorkContainer extends ZorkObject implements HasSetOfCollectable {
open = true;
}
@Override
public Set<String> getSetFromType(ZorkObjectTypes type) {
if (type.equals(ITEM))
return items;
throw new IllegalStateException("Unexpected value: " + type);
public void addObject(final ZorkObject object) {
if (!(object instanceof ZorkItem)) {
throw new UnsupportedOperationException(
"a container cannot store " + object.getClass().getSimpleName() + " objects");
}
addItem(object.getName());
}
@Override
public void removeObject(final ZorkObject object) {
if (!(object instanceof ZorkItem)) {
return;
}
removeItem(object.getName());
}
}

View File

@ -3,7 +3,7 @@ package com.github.dtschust.zork.objects;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.ZorkTrigger;
import com.github.dtschust.zork.types.HasSetOfCollectable;
import com.github.dtschust.zork.types.ObjectCollector;
import com.github.dtschust.zork.types.ZorkDirection;
import java.util.*;
@ -11,7 +11,7 @@ import java.util.*;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.*;
/* Room*/
public class ZorkRoom extends ZorkObject implements HasSetOfCollectable {
public class ZorkRoom extends ZorkObject implements ObjectCollector {
private final String type;
private final Map<ZorkDirection, String> border;
private final Set<String> container;
@ -35,20 +35,6 @@ public class ZorkRoom extends ZorkObject implements HasSetOfCollectable {
this.creature = new HashSet<>(creatures);
}
@Override
public Set<String> getSetFromType(ZorkObjectTypes type) {
switch (type) {
case CONTAINER:
return getContainer();
case CREATURE:
return getCreature();
case ITEM:
return getItem();
default:
throw new IllegalStateException("Unexpected value: " + type);
}
}
public boolean isExit() {
return "exit".equals(type);
}
@ -66,9 +52,9 @@ public class ZorkRoom extends ZorkObject implements HasSetOfCollectable {
}
public boolean evaluateTriggers(ZorkGame game, String input) {
final boolean items = ZorkTrigger.evaluateTriggerCollection(item, ITEM, game, input);
final boolean creatures = ZorkTrigger.evaluateTriggerCollection(creature, CREATURE, game, input);
final boolean containers = ZorkTrigger.evaluateTriggerCollection(container, CONTAINER, game, input);
final boolean items = ZorkTrigger.evaluateTriggersFor(item.stream(), game, input);
final boolean creatures = ZorkTrigger.evaluateTriggersFor(creature.stream(), game, input);
final boolean containers = ZorkTrigger.evaluateTriggersFor(container.stream(), game, input);
return super.evaluateTriggers(game, input) || items || creatures || containers;
}
@ -76,11 +62,31 @@ public class ZorkRoom extends ZorkObject implements HasSetOfCollectable {
return container;
}
public Set<String> getItem() {
return item;
public boolean containsItem(final String item) {
return this.item.contains(item);
}
public Set<String> getCreature() {
return creature;
@Override
public void addObject(ZorkObject object) {
if (object instanceof ZorkContainer) {
container.add(object.getName());
} else if (object instanceof ZorkItem) {
item.add(object.getName());
} else if (object instanceof ZorkCreature) {
creature.add(object.getName());
} else {
throw new UnsupportedOperationException("room cannot store " + object.getClass().getSimpleName() + " objects");
}
}
@Override
public void removeObject(ZorkObject object) {
if (object instanceof ZorkContainer) {
container.remove(object.getName());
} else if (object instanceof ZorkItem) {
item.remove(object.getName());
} else if (object instanceof ZorkCreature) {
creature.remove(object.getName());
}
}
}

View File

@ -1,44 +1,61 @@
package com.github.dtschust.zork.parser;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.objects.*;
import com.github.dtschust.zork.objects.ZorkContainer;
import com.github.dtschust.zork.objects.ZorkCreature;
import com.github.dtschust.zork.objects.ZorkItem;
import com.github.dtschust.zork.objects.ZorkRoom;
import java.io.PrintStream;
import java.util.Map;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.*;
import java.util.ArrayList;
import java.util.List;
public abstract class ZorkParser {
private final Map<ZorkObjectTypes, PropertyParseStrategy<? extends ZorkObject>> strategies;
private final PropertyParseStrategy<ZorkCreature> creatureStrategy;
private final PropertyParseStrategy<ZorkContainer> containerStrategy;
private final PropertyParseStrategy<ZorkItem> itemStrategy;
private final PropertyParseStrategy<ZorkRoom> roomStrategy;
public ZorkParser(final PropertyParseStrategy<ZorkCreature> creatureStrategy,
final PropertyParseStrategy<ZorkContainer> containerStrategy,
final PropertyParseStrategy<ZorkItem> itemStrategy,
final PropertyParseStrategy<ZorkRoom> roomStrategy) {
this.strategies = Map.ofEntries(
Map.entry(CREATURE, creatureStrategy),
Map.entry(CONTAINER, containerStrategy),
Map.entry(ITEM, itemStrategy),
Map.entry(ROOM, roomStrategy)
);
protected ZorkParser(final PropertyParseStrategy<ZorkCreature> creatureStrategy,
final PropertyParseStrategy<ZorkContainer> containerStrategy,
final PropertyParseStrategy<ZorkItem> itemStrategy,
final PropertyParseStrategy<ZorkRoom> roomStrategy) {
this.creatureStrategy = creatureStrategy;
this.containerStrategy = containerStrategy;
this.itemStrategy = itemStrategy;
this.roomStrategy = roomStrategy;
}
protected abstract Property getRootProperty(final String filename);
public ZorkGame parse(final String filename, final PrintStream stream) {
ZorkGame data = new ZorkGame(stream);
final List<ZorkCreature> creatureList = new ArrayList<>();
final List<ZorkContainer> containerList = new ArrayList<>();
final List<ZorkRoom> roomList = new ArrayList<>();
final List<ZorkItem> itemList = new ArrayList<>();
final Property rootElement = getRootProperty(filename);
// Every single first generation child is a room, container, creature, or item. So load them in
for (final Property element : rootElement.subProperties()) {
final String name = element.name();
final ZorkObjectTypes t = ZorkObjectTypes.fromPropertyName(name)
.orElseThrow(() -> new IllegalStateException("Unexpected value: " + name));
final ZorkObject built = strategies.get(t).parse(element);
data.addObjectThroughLookup(t, built);
switch (element.name()) {
case "creature":
creatureList.add(creatureStrategy.parse(element));
break;
case "container":
containerList.add(containerStrategy.parse(element));
break;
case "room":
roomList.add(roomStrategy.parse(element));
break;
case "item":
itemList.add(itemStrategy.parse(element));
break;
default:
throw new IllegalArgumentException(element.name() + " not recognized");
}
}
return data;
return new ZorkGame(roomList, itemList, containerList, creatureList, stream);
}
}

View File

@ -2,9 +2,6 @@ package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.types.HasSetOfCollectable;
import com.github.dtschust.zork.objects.ZorkObjectTypes;
import com.github.dtschust.zork.objects.ZorkObject;
import java.util.List;
@ -25,18 +22,16 @@ public class AddAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String object = arguments.get(1);
final String objectName = arguments.get(1);
final String destination = arguments.get(3);
try {
ZorkObjectTypes destType = game.getTypeFromLookup(destination);
ZorkObjectTypes objType = game.getTypeFromLookup(object);
ZorkObject tempObject = game.get(destType, destination);
((HasSetOfCollectable) tempObject).getSetFromType(objType).add(object);
game.put(destType, tempObject);
} catch (Exception e) {
return game.getObject(objectName).map(o -> {
game.addObjectToCollection(o, destination);
return true;
}).orElse(false);
} catch (final UnsupportedOperationException ignored) {
return false;
}
return true;
}
}

View File

@ -1,19 +1,18 @@
package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.objects.ZorkCreature;
import com.github.dtschust.zork.repl.Action;
import java.util.List;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.CREATURE;
import java.util.Optional;
/**
* Attempt an attack, do you feel lucky?
*/
public class AttackAction implements Action {
@Override
public boolean matchesInput(List<String> arguments) {
public boolean matchesInput(final List<String> arguments) {
return arguments.get(0).equals("attack");
}
@ -23,17 +22,16 @@ public class AttackAction implements Action {
}
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String tempString = arguments.get(1);
public boolean run(final ZorkGame game, final List<String> arguments) {
final String what = arguments.get(1);
final String weapon = arguments.get(3);
if (game.getCurrentRoom().getCreature().contains(tempString)) {
ZorkCreature tempCreature = (ZorkCreature) game.get(CREATURE, tempString);
if (tempCreature != null && game.inventory.contains(weapon) && tempCreature.isAttackSuccessful(game, weapon)) {
game.stream.println("You assault the " + tempString + " with the " + weapon + ".");
tempCreature.printAndExecuteActions(game);
return true;
}
final Optional<ZorkCreature> tempCreature = game.getCreature(what);
if (tempCreature.isPresent() && game.inventory.contains(weapon) &&
tempCreature.get().isAttackSuccessful(game, weapon)) {
game.stream.println("You assault the " + what + " with the " + weapon + ".");
tempCreature.get().printAndExecuteActions(game);
return true;
}
return false;
}

View File

@ -1,8 +1,9 @@
package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.objects.ZorkItem;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.types.HasSetOfCollectable;
import com.github.dtschust.zork.types.ObjectCollector;
import com.github.dtschust.zork.objects.ZorkObjectTypes;
import com.github.dtschust.zork.objects.ZorkObject;
import com.github.dtschust.zork.objects.ZorkRoom;
@ -16,15 +17,6 @@ import static com.github.dtschust.zork.objects.ZorkObjectTypes.*;
* Delete: figure out what object it is and delete it accordingly. Rooms are especially tricky
*/
public class DeleteAction implements Action {
private static void deleteElementFromSpace(ZorkGame game, ZorkObjectTypes space, ZorkObjectTypes element, String object) {
for (ZorkObject tempObject : game.values(ZorkObject.class, space)) {
Set<String> set = ((HasSetOfCollectable) tempObject).getSetFromType(element);
if (set.contains(object)) {
set.remove(object);
game.put(space, tempObject);
}
}
}
@Override
public boolean matchesInput(List<String> arguments) {
@ -38,26 +30,13 @@ public class DeleteAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String object = arguments.get(1);
switch (game.getTypeFromLookup(object)) {
case ROOM:
for (final ZorkRoom tempRoom : game.values(ZorkRoom.class, ROOM)) {
tempRoom.removeBorderingRoom(object);
game.put(ROOM, tempRoom);
}
break;
case ITEM:
deleteElementFromSpace(game, ROOM, ITEM, object);
deleteElementFromSpace(game, CONTAINER, ITEM, object);
break;
case CONTAINER:
deleteElementFromSpace(game, ROOM, CONTAINER, object);
break;
case CREATURE:
deleteElementFromSpace(game, ROOM, CREATURE, object);
break;
}
return true;
return game.getObject(arguments.get(1)).map(o -> {
if (o instanceof ZorkRoom) {
game.removeFromBorders((ZorkRoom) o);
} else {
game.removeObjectFromCollections(o);
}
return true;
}).orElse(false);
}
}

View File

@ -1,12 +1,12 @@
package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.objects.ZorkItem;
import com.github.dtschust.zork.objects.ZorkRoom;
import com.github.dtschust.zork.repl.Action;
import java.util.List;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.ROOM;
import java.util.Optional;
public class DropItemAction implements Action {
@Override
@ -21,17 +21,19 @@ public class DropItemAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String what = arguments.get(1);
final String whatName = arguments.get(1);
final Optional<ZorkItem> what = game.getItem(whatName);
if (game.inventory.contains(what)) {
ZorkRoom tempRoom = game.getCurrentRoom();
tempRoom.getItem().add(what);
game.put(ROOM, tempRoom);
game.inventory.remove(what);
game.stream.println(what + " dropped.");
if (game.inventory.contains(whatName) && what.isPresent()) {
final ZorkRoom tempRoom = game.getCurrentRoom();
game.inventory.remove(whatName);
tempRoom.addObject(what.get());
game.stream.println(whatName + " dropped.");
return true;
} else {
return false;
}
return true;
}
}

View File

@ -13,6 +13,7 @@ public class InventoryAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
if (game.inventory.isEmpty()) {
game.stream.println("Inventory: empty");
} else {

View File

@ -2,12 +2,9 @@ package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.objects.ZorkContainer;
import java.util.List;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.CONTAINER;
public class OpenAction implements Action {
@Override
public boolean matchesInput(List<String> arguments) {
@ -22,19 +19,16 @@ public class OpenAction implements Action {
if (game.getCurrentRoom().isExit()) {
game.stream.println("Game Over");
game.setGameOver();
return true;
} else {
return false;
}
} else {
ZorkContainer tempContainer;
if (game.getCurrentRoom().getContainer().contains(what)) {
tempContainer = (ZorkContainer) game.get(CONTAINER, what);
tempContainer.open();
game.stream.println(tempContainer.getContents());
} else {
return false;
}
return game.getContainer(what).map(cont -> {
cont.open();
game.stream.println(cont.getContents());
return true;
}).orElse(false);
}
return true;
}
}

View File

@ -2,12 +2,9 @@ package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.objects.ZorkContainer;
import java.util.List;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.CONTAINER;
public class PutAction implements Action {
@Override
public boolean matchesInput(List<String> arguments) {
@ -22,17 +19,13 @@ public class PutAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String what = arguments.get(1);
final String destination = arguments.get(3);
if (game.getCurrentRoom().getContainer().contains(destination)) {
ZorkContainer tempContainer = (ZorkContainer) game.get(CONTAINER, destination);
if (tempContainer.isOpen() && game.inventory.contains(what)) {
return game.getContainer(arguments.get(3))
.filter(c -> c.isOpen() && game.inventory.contains(what))
.map(tempContainer -> {
tempContainer.addItem(what);
game.inventory.remove(what);
game.stream.println("Item " + what + " added to " + destination + ".");
game.stream.println("Item " + what + " added to " + tempContainer.getName() + ".");
return true;
}
}
return false;
}).orElse(false);
}
}

View File

@ -21,13 +21,9 @@ public class ReadAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String what = arguments.get(1);
if (game.inventory.contains(what)) {
ZorkItem tempItem = (ZorkItem) game.get(ITEM, what);
game.stream.println(tempItem.getWriting());
return game.getItem(arguments.get(1)).map(i -> {
game.stream.println(i.getWriting());
return true;
}
return false;
}).orElse(false);
}
}

View File

@ -1,14 +1,12 @@
package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.objects.ZorkContainer;
import com.github.dtschust.zork.objects.ZorkRoom;
import com.github.dtschust.zork.objects.ZorkItem;
import com.github.dtschust.zork.repl.Action;
import java.util.List;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.CONTAINER;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.ROOM;
import java.util.Optional;
public class TakeAction implements Action {
@Override
@ -23,28 +21,27 @@ public class TakeAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String tempString = arguments.get(1);
if ((game.getCurrentRoom()).getItem().contains(tempString)) {
game.inventory.add(tempString);
ZorkRoom tempRoom = (game.getCurrentRoom());
tempRoom.getItem().remove(tempString);
game.put(ROOM, tempRoom);
game.stream.println("Item " + tempString + " added to inventory.");
return true;
} else {
/* Search all containers in the current room for the item! */
for (String key : game.getCurrentRoom().getContainer()) {
ZorkContainer tempContainer = (ZorkContainer) game.get(CONTAINER, key);
if (tempContainer != null && tempContainer.isOpen() && tempContainer.containsItem(tempString)) {
game.inventory.add(tempString);
tempContainer.removeItem(tempString);
game.put(CONTAINER, tempContainer);
game.stream.println("Item " + tempString + " added to inventory.");
return true;
return game.getItem(arguments.get(1)).map(i -> {
if (game.getCurrentRoom().containsItem(i.getName())) {
game.inventory.add(i.getName());
game.getCurrentRoom().removeObject(i);
game.stream.println("Item " + i.getName() + " added to inventory.");
return true;
} else {
// Search all containers in the current room for the item!
for (final String key : game.getCurrentRoom().getContainer()) {
final ZorkContainer tempContainer = game.getContainer(key).orElseThrow(() ->
new IllegalStateException("container " + key + " in room " +
game.getCurrentRoom().getName() + " not found"));
if (tempContainer != null && tempContainer.isOpen() && tempContainer.containsItem(i.getName())) {
game.inventory.add(i.getName());
tempContainer.removeObject(i);
game.stream.println("Item " + i.getName() + " added to inventory.");
return true;
}
}
}
return false;
}
}).orElse(false);
}
}

View File

@ -2,11 +2,9 @@ package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.objects.ZorkItem;
import java.util.List;
import static com.github.dtschust.zork.objects.ZorkObjectTypes.ITEM;
import java.util.Optional;
/**
* Turn on an item
@ -25,15 +23,14 @@ public class TurnOnAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String what = arguments.get(2);
final boolean inInventory = game.inventory.contains(what);
if (game.inventory.contains(what)) {
ZorkItem tempItem = (ZorkItem) game.get(ITEM, what);
game.stream.println("You activate the " + what + ".");
if (tempItem != null) {
tempItem.printAndExecuteActions(game);
return true;
}
}
return false;
return Optional.ofNullable(inInventory ? what : null)
.flatMap(game::getItem)
.map(i -> {
game.stream.println("You activate the " + i.getName() + ".");
i.printAndExecuteActions(game);
return true;
}).orElse(false);
}
}

View File

@ -2,8 +2,6 @@ package com.github.dtschust.zork.repl.actions;
import com.github.dtschust.zork.ZorkGame;
import com.github.dtschust.zork.repl.Action;
import com.github.dtschust.zork.types.ZorkMap;
import com.github.dtschust.zork.objects.ZorkObject;
import java.util.List;
@ -23,13 +21,10 @@ public class UpdateAction implements Action {
@Override
public boolean run(ZorkGame game, List<String> arguments) {
final String object = arguments.get(1);
final String objectName = arguments.get(1);
final String newStatus = arguments.get(3);
ZorkMap<ZorkObject> collection = game.getListThroughLookup(ZorkObject.class, object);
ZorkObject tempObject = collection.get(object);
tempObject.updateStatus(newStatus);
collection.put(tempObject);
game.updateObjectStatus(objectName, newStatus);
return true;
}
}

View File

@ -1,12 +0,0 @@
package com.github.dtschust.zork.types;
import com.github.dtschust.zork.objects.ZorkObjectTypes;
import java.util.Set;
public interface HasSetOfCollectable {
default Set<String> getSetFromType(ZorkObjectTypes type) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,11 @@
package com.github.dtschust.zork.types;
import com.github.dtschust.zork.objects.ZorkObject;
import com.github.dtschust.zork.objects.ZorkObjectTypes;
import java.util.Set;
public interface ObjectCollector {
void addObject(final ZorkObject object);
void removeObject(final ZorkObject object);
}

View File

@ -1,19 +0,0 @@
package com.github.dtschust.zork.types;
import com.github.dtschust.zork.objects.ZorkObject;
import java.util.HashMap;
import java.util.Iterator;
public class ZorkMap<T extends ZorkObject> extends HashMap<String, T> implements Iterable<T> {
public void put(T object) {
put(object.getName(), object);
}
@Override
public Iterator<T> iterator() {
return this.values().iterator();
}
}

View File

@ -0,0 +1,34 @@
package com.github.dtschust.zork.types;
import com.github.dtschust.zork.objects.ZorkObject;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ZorkMapByName<T extends ZorkObject> {
private final Map<String, T> backing;
public ZorkMapByName(final Collection<T> source) {
backing = source.stream().collect(Collectors.toMap(ZorkObject::getName, Function.identity()));
}
public void put(final T object) {
backing.put(object.getName(), object);
}
public Optional<T> get(final String name) {
return Optional.ofNullable(backing.get(name));
}
public boolean containsName(final String name) {
return backing.containsKey(name);
}
public Collection<T> values() {
return backing.values();
}
}

View File

@ -4,6 +4,8 @@ import com.github.dtschust.zork.utils.CommandReader;
import com.github.dtschust.zork.utils.IOWrapper;
import org.junit.jupiter.api.Test;
import java.io.PrintStream;
import static com.github.stefanbirkner.systemlambda.SystemLambda.catchSystemExit;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -17,12 +19,16 @@ class ZorkTest {
String gameConfig = "sampleGame.xml";
String gameExecution = "RunThroughResults.txt";
PrintStream out = System.out;
CommandReader run = new CommandReader(gameExecution);
IOWrapper io = new IOWrapper(true);
new Thread(() -> {
try {
catchSystemExit(() -> new Zork(gameConfig));
} catch (Exception ignored) {}
} catch (Exception ignored) {
ignored.printStackTrace(out);
}
}).start();
while(true){
switch(run.getInstructionType()) {