This repository has been archived on 2022-12-21. You can view files and clone it, but cannot push or open issues or pull requests.
sdm03/src/main/java/com/github/dtschust/zork/Zork.java

456 lines
16 KiB
Java

/*Drew Schuster
dtschust
ECE462
*/
package com.github.dtschust.zork;
import com.github.dtschust.zork.parser.ZorkGame;
import com.github.dtschust.zork.types.*;
import com.github.dtschust.zork.parser.ZorkReader;
import java.util.Map;
import java.util.Scanner;
import static java.util.Map.entry;
/* And away we go*/
public class Zork {
public String userInput;
public ZorkGame game;
Scanner source = new Scanner(System.in);
public Zork(String filename) {
game = new ZorkReader(filename).build();
game.changeRoom("Entrance");
/* Print out the first entrance description, starting the game!*/
System.out.println(game.getCurrentRoom().description);
/* There is no stopping in Zork, until we're done!!*/
while(game.isRunning()) {
userInput = source.nextLine();
/*Now that we have the user command, check the input*/
if (!executeTriggers()) {
/* If we haven't skipped, perform the user action*/
executeAction(userInput);
/* Clear the user input, and check the triggers again (various states have changed, gnomes need to be found!*/
userInput = "";
executeTriggers();
}
}
// single point of termination
System.exit(0);
}
/* I love how basic java main functions are sometimes.*/
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: java Zork [filename]");
return;
}
new Zork(args[0]);
}
public void executeAction(String input) {
String[] action = input.split(" ");
/* Update: figure out what type of item it is, and then change it's status*/
if (action[0].equals("Update")) {
doActionUpdate(action[1], action[3]);
}
/*Game Over: pretty straight forward*/
else if (input.equals("Game Over")) {
doActionGameWon();
}
/* Add: figure out what type the destination is, then what type the object is. Then add object to destination if it makes sense */
else if (action[0].equals("Add")) {
doActionAdd(action[1], action[3]);
}
/* Delete: figure out what object it is and delete it accordingly. Rooms are especially tricky */
else if (action[0].equals("Delete")) {
doActionDelete(action[1]);
}
/*If it's not a "Special Action", just treat it normally */
/* Execute a user action or an action command from some <action> element that is not one of the "Special Commands"*/
/* Movement */
else if (action[0].length() == 1 && "nswe".contains(action[0])) {
doActionMove(action[0]);
}
/* Inventory */
else if (action[0].equals("i")) {
doActionInventory();
}
/* Take */
else if (action[0].equals("take") && action.length > 1) {
doActionTake(action[1]);
}
/* Open Exit (you should be so lucky)*/
else if (input.equals("open exit")) {
doActionOpenExit();
}
/* Open a container */
else if (action[0].equals("open") && action.length > 1) {
doActionOpenContainer(action[1]);
}
/* Read an object */
else if (action[0].equals("read") && action.length > 1) {
doActionReadObject(action[1]);
}
/* Drop an item*/
else if (action[0].equals("drop") && action.length > 1) {
doActionDropItem(action[1]);
}
/* Put an item somewhere */
else if (action[0].equals("put") && action.length >= 4) {
doActionPutItem(action[1], action[3]);
}
/* Turn on an item*/
else if (input.startsWith("turn on") && action.length >= 3) {
doActionTurnOn(action[2]);
}
/* Attempt an attack, you feeling lucky?*/
else if (action[0].equals("attack") && action.length >= 4) {
doActionAttack(action[1], action[3]);
}
/* Invalid command*/
else System.out.println("Error");
}
private void doActionGameWon() {
System.out.println("Victory!");
game.setGameOver();
}
private void doActionAdd(String object, String destination) {
String objectType;
objectType = game.getTypeFromLookup(object);
String destinationType = game.getTypeFromLookup(destination);
if (destinationType.equals("room")) {
ZorkRoom tempRoom = (ZorkRoom) game.get("room", destination);
if (objectType.equals("item"))
tempRoom.item.add(object);
else if (objectType.equals("creature"))
tempRoom.creature.add(object);
else if (objectType.equals("container"))
tempRoom.container.add(object);
else
System.out.println("Error");
game.put("room", tempRoom);
} else if (destinationType.equals("container")) {
ZorkContainer tempContainer = (ZorkContainer) game.get("container", destination);
if (objectType.equals("item"))
tempContainer.item.add(object);
else
System.out.println("Error");
game.put("container", tempContainer);
} else {
System.out.println("Error");
}
}
private void doActionDelete(String object) {
String objectType = game.getTypeFromLookup(object);
if (objectType.equals("room")) {
for (ZorkRoom tempRoom : (Iterable<ZorkRoom>) game.values("room")) {
for (String key : tempRoom.border.keySet()) {
if (tempRoom.border.get(key).equals(object)) {
tempRoom.border.remove(key);
}
}
game.put("room", tempRoom);
}
} else if (objectType.equals("item")) {
for (ZorkRoom tempRoom : (Iterable<ZorkRoom>) game.values("room")) {
if (tempRoom.item.contains(object)) {
tempRoom.item.remove(object);
game.put("room", tempRoom);
}
}
for (ZorkContainer tempContainer : (Iterable<ZorkContainer>) game.values("container")) {
if (tempContainer.item.contains(object)) {
tempContainer.item.remove(object);
game.put("container", tempContainer);
}
}
} else if (objectType.equals("container")) {
for (ZorkRoom tempRoom : (Iterable<ZorkRoom>) game.values("room")) {
if (tempRoom.container.contains(object)) {
tempRoom.container.remove(object);
game.put("room", tempRoom);
}
}
} else if (objectType.equals("creature")) {
for (ZorkRoom tempRoom : (Iterable<ZorkRoom>) game.values("room")) {
if (tempRoom.creature.contains(object)) {
tempRoom.creature.remove(object);
game.put("room", tempRoom);
}
}
}
}
private void doActionUpdate(String object, String newStatus) {
ZorkMap<ZorkObject> collection = (ZorkMap<ZorkObject>) game.getListThroughLookup(object);
ZorkObject tempObject = collection.get(object);
tempObject.updateStatus(newStatus);
collection.put(tempObject);
}
private void doActionAttack(String tempString, String weapon) {
if (game.getCurrentRoom().creature.contains(tempString)) {
ZorkCreature tempCreature = (ZorkCreature) game.get("creature", tempString);
if (tempCreature != null && game.inventory.contains(weapon)) {
if (tempCreature.attack(this, weapon)) {
System.out.println("You assault the " + tempString + " with the " + weapon + ".");
for (String print: tempCreature.print) {
System.out.println(print);
}
for (String action: tempCreature.action) {
executeAction(action);
}
return;
}
}
}
System.out.println("Error");
}
private void doActionTurnOn(String tempString) {
if (game.inventory.contains(tempString)) {
ZorkItem tempItem = (ZorkItem) game.get("item", tempString);
System.out.println("You activate the " + tempString + ".");
if (tempItem != null) {
for (String print: tempItem.turnOnPrint) {
System.out.println(print);
}
for (String action: tempItem.turnOnAction) {
executeAction(action);
}
return;
}
}
System.out.println("Error");
}
private void doActionPutItem(String tempString, String destination) {
if (game.getCurrentRoom().container.contains(destination)){
ZorkContainer tempContainer = (ZorkContainer) game.get("container", destination);
if(tempContainer.isOpen() && game.inventory.contains(tempString)) {
tempContainer.item.add(tempString);
game.inventory.remove(tempString);
System.out.println("Item " + tempString + " added to " + destination + ".");
return;
}
}
System.out.println("Error");
}
private void doActionDropItem(String tempString) {
if (game.inventory.contains(tempString)) {
ZorkRoom tempRoom = game.getCurrentRoom();
tempRoom.item.add(tempString);
game.put("room", tempRoom);
game.inventory.remove(tempString);
System.out.println(tempString + " dropped.");
} else {
System.out.println("Error");
}
}
private void doActionReadObject(String tempString) {
if (game.inventory.contains(tempString)) {
ZorkItem tempItem = (ZorkItem) game.get("item", tempString);
if (tempItem.writing != null && !tempItem.writing.isEmpty()) {
System.out.println(tempItem.writing);
} else {
System.out.println("Nothing written.");
}
} else {
System.out.println("Error");
}
}
private void doActionOpenContainer(String tempString) {
ZorkContainer tempContainer;
if (game.getCurrentRoom().container.contains(tempString)) {
tempContainer = (ZorkContainer) game.get("container", tempString);
tempContainer.open();
if (tempContainer.item.isEmpty()) {
System.out.println(tempString + " is empty");
} else {
String output = "";
System.out.print(tempString + " contains ");
for (String key : tempContainer.item) {
output += key + ", ";
}
output = output.substring(0, output.length() - 2);
System.out.println(output + ".");
}
} else {
System.out.println("Error");
}
}
private void doActionOpenExit() {
if (game.getCurrentRoom().type.equals("exit")) {
System.out.println("Game Over");
game.setGameOver();
} else {
System.out.println("Error");
}
}
/*Basic movement function */
private void doActionMove(String direction) {
final Map<String, String> fullDirections = Map.ofEntries(
entry("n", "north"),
entry("s", "south"),
entry("e", "east"),
entry("w", "west")
);
if (game.changeRoom(game.getCurrentRoom().border.get(fullDirections.get(direction)))) {
System.out.println(game.getCurrentRoom().description);
} else {
System.out.println("Can't go that way.");
}
}
/* Print out the inventory when user types i */
private void doActionInventory() {
String output = "Inventory: ";
if (game.inventory.isEmpty()) {
System.out.println("Inventory: empty");
} else {
for (String key : game.inventory) {
output += key + ", ";
}
output = output.substring(0, output.length() - 2);
System.out.println(output);
}
}
private void doActionTake(String tempString) {
if ((game.getCurrentRoom()).item.contains(tempString)) {
game.inventory.add(tempString);
ZorkRoom tempRoom = (game.getCurrentRoom());
tempRoom.item.remove(tempString);
game.put("room", tempRoom);
System.out.println("Item " + tempString + " added to inventory.");
} else {
/*Search all containers in the current room for the item!*/
for (String key : game.getCurrentRoom().container) {
ZorkContainer tempContainer = (ZorkContainer) game.get("container", key);
if (tempContainer != null && tempContainer.isOpen() && tempContainer.item.contains(tempString)) {
game.inventory.add(tempString);
tempContainer.item.remove(tempString);
game.put("container", tempContainer);
System.out.println("Item " + tempString + " added to inventory.");
return;
}
}
System.out.println("Error");
}
}
/* Check triggers */
public boolean executeTriggers() {
/*Variable initialization*/
boolean skip = false;
/*Check Room triggers*/
skip = skip || doTriggersRoom();
/* Check items in the containers in the room */
skip = skip || doTriggersItemsInContainersInRoom();
/* Check all containers in the room*/
skip = skip || doTriggersContainersInRoom();
/* Check all creatures in the room */
skip = skip || doTriggersCreaturesInRoom();
/* Check items in inventory */
skip = skip || doTriggersItemsInInventory();
/* Check items in room */
skip = skip || doTriggersItemsInRoom();
return skip;
}
private boolean doTriggersContainersInRoom() {
boolean skip = false;
for (String key : game.getCurrentRoom().container) {
skip = skip || doZorkTriggers(game.get("container", key));
}
return skip;
}
private boolean doTriggersItemsInContainersInRoom() {
boolean skip = false;
for (String key : game.getCurrentRoom().container) {
ZorkContainer tempContainer = (ZorkContainer) game.get("container", key);
for (String key2 : tempContainer.item) {
skip = skip || doZorkTriggers(game.get("item", key2));
}
}
return skip;
}
private boolean doTriggersItemsInRoom() {
boolean skip = false;
for (String key : game.getCurrentRoom().item) {
skip = skip || doZorkTriggers(game.get("item", key));
}
return skip;
}
private boolean doTriggersItemsInInventory() {
boolean skip = false;
for (String key : game.inventory) {
skip = skip || doZorkTriggers(game.get("item", key));
}
return skip;
}
private boolean doTriggersCreaturesInRoom() {
boolean skip = false;
for (String key : game.getCurrentRoom().creature) {
skip = skip || doZorkTriggers(game.get("creature", key));
}
return skip;
}
private boolean doTriggersRoom() {
return doZorkTriggers(game.getCurrentRoom());
}
private boolean doZorkTriggers(ZorkObject zorkObject) {
boolean skip = false;
for (int x = zorkObject.trigger.size() - 1; x >= 0; x--) {
ZorkTrigger tempTrigger = zorkObject.trigger.get(x);
if (tempTrigger.evaluate(this)) {
for (String print: tempTrigger.print) {
System.out.println(print);
}
for (String action: tempTrigger.action) {
executeAction(action);
}
skip = skip || tempTrigger.hasCommand;
if (tempTrigger.type.equals("single")) {
zorkObject.trigger.remove(x);
}
}
}
return skip;
}
}