diff --git a/data/rooms.dat b/data/rooms.dat new file mode 100644 index 0000000..0ee90dc --- /dev/null +++ b/data/rooms.dat @@ -0,0 +1,9 @@ +Room Name: Room 1 +Room Description: This is room
1 +Exit Rooms: E-Room 2 +Room Name: Room 2 +Room Description: This is Room 2 +Exit Rooms: W-Room 1, U-Room 3 +Room Name: Room 3 +Room Description: You are upstairs. +Exit Rooms: D-Room 2 diff --git a/src/com/bayviewglen/zork/Command.java b/src/com/bayviewglen/zork/Command.java new file mode 100644 index 0000000..1e80b73 --- /dev/null +++ b/src/com/bayviewglen/zork/Command.java @@ -0,0 +1,66 @@ +package com.bayviewglen.zork; + +/** + * Class Command - Part of the "Zork" game. + * + * author: Michael Kolling version: 1.0 date: July 1999 + * + * This class holds information about a command that was issued by the user. A + * command currently consists of two strings: a command word and a second word + * (for example, if the command was "take map", then the two strings obviously + * are "take" and "map"). + * + * The way this is used is: Commands are already checked for being valid command + * words. If the user entered an invalid command (a word that is not known) then + * the command word is . + * + * If the command had only one word, then the second word is . + * + * The second word is not checked at the moment. It can be anything. If this + * game is extended to deal with items, then the second part of the command + * should probably be changed to be an item rather than a String. + */ +class Command { + private String commandWord; + private String secondWord; + + /** + * Create a command object. First and second word must be supplied, but + * either one (or both) can be null. The command word should be null to + * indicate that this was a command that is not recognised by this game. + */ + public Command(String firstWord, String secondWord) { + commandWord = firstWord; + this.secondWord = secondWord; + } + + /** + * Return the command word (the first word) of this command. If the command + * was not understood, the result is null. + */ + public String getCommandWord() { + return commandWord; + } + + /** + * Return the second word of this command. Returns null if there was no + * second word. + */ + public String getSecondWord() { + return secondWord; + } + + /** + * Return true if this command was not understood. + */ + public boolean isUnknown() { + return (commandWord == null); + } + + /** + * Return true if the command has a second word. + */ + public boolean hasSecondWord() { + return (secondWord != null); + } +} diff --git a/src/com/bayviewglen/zork/CommandWords.java b/src/com/bayviewglen/zork/CommandWords.java new file mode 100644 index 0000000..643f06d --- /dev/null +++ b/src/com/bayviewglen/zork/CommandWords.java @@ -0,0 +1,46 @@ +package com.bayviewglen.zork; + +/* + * Author: Michael Kolling. + * Version: 1.0 + * Date: July 1999 + * + * This class holds an enumeration of all command words known to the game. + * It is used to recognise commands as they are typed in. + * + * This class is part of the "Zork" game. + */ +class CommandWords { + // a constant array that holds all valid command words + private static final String validCommands[] = { "go", "quit", "help", "eat" }; + + /** + * Constructor - initialise the command words. + */ + public CommandWords() { + // nothing to do at the moment... + } + + /** + * Check whether a given String is a valid command word. Return true if it + * is, false if it isn't. + **/ + public boolean isCommand(String aString) { + for (int i = 0; i < validCommands.length; i++) { + if (validCommands[i].equals(aString)) + return true; + } + // if we get here, the string was not found in the commands + return false; + } + + /* + * Print all valid commands to System.out. + */ + public void showAll() { + for (int i = 0; i < validCommands.length; i++) { + System.out.print(validCommands[i] + " "); + } + System.out.println(); + } +} diff --git a/src/com/bayviewglen/zork/Game.java b/src/com/bayviewglen/zork/Game.java new file mode 100644 index 0000000..4a95847 --- /dev/null +++ b/src/com/bayviewglen/zork/Game.java @@ -0,0 +1,190 @@ +package com.bayviewglen.zork; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Scanner; + +/** + * Class Game - the main class of the "Zork" game. + * + * Author: Michael Kolling Version: 1.1 Date: March 2000 + * + * This class is the main class of the "Zork" application. Zork is a very + * simple, text based adventure game. Users can walk around some scenery. That's + * all. It should really be extended to make it more interesting! + * + * To play this game, create an instance of this class and call the "play" + * routine. + * + * This main class creates and initialises all the others: it creates all rooms, + * creates the parser and starts the game. It also evaluates the commands that + * the parser returns. + */ +class Game { + private Parser parser; + private Room currentRoom; + // This is a MASTER object that contains all of the rooms and is easily + // accessible. + // The key will be the name of the room -> no spaces (Use all caps and + // underscore -> Great Room would have a key of GREAT_ROOM + // In a hashmap keys are case sensitive. + // masterRoomMap.get("GREAT_ROOM") will return the Room Object that is the + // Great Room (assuming you have one). + private HashMap masterRoomMap; + + private void initRooms(String fileName) throws Exception { + masterRoomMap = new HashMap(); + Scanner roomScanner; + try { + HashMap> exits = new HashMap>(); + roomScanner = new Scanner(new File(fileName)); + while (roomScanner.hasNext()) { + Room room = new Room(); + // Read the Name + String roomName = roomScanner.nextLine(); + room.setRoomName(roomName.split(":")[1].trim()); + // Read the Description + String roomDescription = roomScanner.nextLine(); + room.setDescription(roomDescription.split(":")[1].replaceAll("
", "\n").trim()); + // Read the Exits + String roomExits = roomScanner.nextLine(); + // An array of strings in the format E-RoomName + String[] rooms = roomExits.split(":")[1].split(","); + HashMap temp = new HashMap(); + for (String s : rooms) { + temp.put(s.split("-")[0].trim(), s.split("-")[1]); + } + + exits.put(roomName.substring(10).trim().toUpperCase().replaceAll(" ", "_"), temp); + + // This puts the room we created (Without the exits in the + // masterMap) + masterRoomMap.put(roomName.toUpperCase().substring(10).trim().replaceAll(" ", "_"), room); + + // Now we better set the exits. + } + + for (String key : masterRoomMap.keySet()) { + Room roomTemp = masterRoomMap.get(key); + HashMap tempExits = exits.get(key); + for (String s : tempExits.keySet()) { + // s = direction + // value is the room. + + String roomName2 = tempExits.get(s.trim()); + Room exitRoom = masterRoomMap.get(roomName2.toUpperCase().replaceAll(" ", "_")); + roomTemp.setExit(s.trim().charAt(0), exitRoom); + + } + + } + + roomScanner.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * Create the game and initialise its internal map. + */ + public Game() { + try { + initRooms("data/Rooms.dat"); + currentRoom = masterRoomMap.get("ROOM_1"); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + parser = new Parser(); + } + + /** + * Main play routine. Loops until end of play. + */ + public void play() { + printWelcome(); + // Enter the main command loop. Here we repeatedly read commands and + // execute them until the game is over. + + boolean finished = false; + while (!finished) { + Command command = parser.getCommand(); + finished = processCommand(command); + } + System.out.println("Thank you for playing. Good bye."); + } + + /** + * Print out the opening message for the player. + */ + private void printWelcome() { + System.out.println(); + System.out.println("Welcome to Zork!"); + System.out.println("Zork is a new, incredibly boring adventure game."); + System.out.println("Type 'help' if you need help."); + System.out.println(); + System.out.println(currentRoom.longDescription()); + } + + /** + * Given a command, process (that is: execute) the command. If this command + * ends the game, true is returned, otherwise false is returned. + */ + private boolean processCommand(Command command) { + if (command.isUnknown()) { + System.out.println("I don't know what you mean..."); + return false; + } + String commandWord = command.getCommandWord(); + if (commandWord.equals("help")) + printHelp(); + else if (commandWord.equals("go")) + goRoom(command); + else if (commandWord.equals("quit")) { + if (command.hasSecondWord()) + System.out.println("Quit what?"); + else + return true; // signal that we want to quit + } else if (commandWord.equals("eat")) { + System.out.println("Do you really think you should be eating at a time like this?"); + } + return false; + } + + // implementations of user commands: + /** + * Print out some help information. Here we print some stupid, cryptic + * message and a list of the command words. + */ + private void printHelp() { + System.out.println("You are lost. You are alone. You wander"); + System.out.println("around at Monash Uni, Peninsula Campus."); + System.out.println(); + System.out.println("Your command words are:"); + parser.showCommands(); + } + + /** + * Try to go to one direction. If there is an exit, enter the new room, + * otherwise print an error message. + */ + private void goRoom(Command command) { + if (!command.hasSecondWord()) { + // if there is no second word, we don't know where to go... + System.out.println("Go where?"); + return; + } + String direction = command.getSecondWord(); + // Try to leave current room. + Room nextRoom = currentRoom.nextRoom(direction); + if (nextRoom == null) + System.out.println("There is no door!"); + else { + currentRoom = nextRoom; + System.out.println(currentRoom.longDescription()); + } + } + +} diff --git a/src/com/bayviewglen/zork/Parser.java b/src/com/bayviewglen/zork/Parser.java new file mode 100644 index 0000000..c33f2e2 --- /dev/null +++ b/src/com/bayviewglen/zork/Parser.java @@ -0,0 +1,66 @@ + +package com.bayviewglen.zork; + +/* + * Author: Michael Kolling + * Version: 1.0 + * Date: July 1999 + * + * This class is part of Zork. Zork is a simple, text based adventure game. + * + * This parser reads user input and tries to interpret it as a "Zork" + * command. Every time it is called it reads a line from the terminal and + * tries to interpret the line as a two word command. It returns the command + * as an object of class Command. + * + * The parser has a set of known command words. It checks user input against + * the known commands, and if the input is not one of the known commands, it + * returns a command object that is marked as an unknown command. + */ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +class Parser { + private CommandWords commands; // holds all valid command words + + public Parser() { + commands = new CommandWords(); + } + + public Command getCommand() { + String inputLine = ""; // will hold the full input line + String word1; + String word2; + System.out.print("> "); // print prompt + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + try { + inputLine = reader.readLine(); + } catch (java.io.IOException exc) { + System.out.println("There was an error during reading: " + exc.getMessage()); + } + StringTokenizer tokenizer = new StringTokenizer(inputLine); + if (tokenizer.hasMoreTokens()) + word1 = tokenizer.nextToken(); // get first word + else + word1 = null; + if (tokenizer.hasMoreTokens()) + word2 = tokenizer.nextToken(); // get second word + else + word2 = null; + // note: we just ignore the rest of the input line. + // Now check whether this word is known. If so, create a command + // with it. If not, create a "nil" command (for unknown command). + if (commands.isCommand(word1)) + return new Command(word1, word2); + else + return new Command(null, word2); + } + + /** + * Print out a list of valid command words. + */ + public void showCommands() { + commands.showAll(); + } +} diff --git a/src/com/bayviewglen/zork/Room.java b/src/com/bayviewglen/zork/Room.java new file mode 100644 index 0000000..b84c1b8 --- /dev/null +++ b/src/com/bayviewglen/zork/Room.java @@ -0,0 +1,144 @@ + +package com.bayviewglen.zork; + +/* + * Class Room - a room in an adventure game. + * + * Author: Michael Kolling + * Version: 1.1 + * Date: August 2000 + * + * This class is part of Zork. Zork is a simple, text based adventure game. + * + * "Room" represents one location in the scenery of the game. It is + * connected to at most four other rooms via exits. The exits are labelled + * north, east, south, west. For each direction, the room stores a reference + * to the neighbouring room, or null if there is no exit in that direction. + */ +import java.util.Set; +import java.util.HashMap; +import java.util.Iterator; + +class Room { + private String roomName; + private String description; + private HashMap exits; // stores exits of this room. + + /** + * Create a room described "description". Initially, it has no exits. + * "description" is something like "a kitchen" or "an open court yard". + */ + public Room(String description) { + this.description = description; + exits = new HashMap(); + } + + public Room() { + // default constructor. + roomName = "DEFAULT ROOM"; + description = "DEFAULT DESCRIPTION"; + exits = new HashMap(); + } + + public void setExit(char direction, Room r) throws Exception { + String dir = ""; + switch (direction) { + case 'E': + dir = "east"; + break; + case 'W': + dir = "west"; + break; + case 'S': + dir = "south"; + break; + case 'N': + dir = "north"; + break; + case 'U': + dir = "up"; + break; + case 'D': + dir = "down"; + break; + default: + throw new Exception("Invalid Direction"); + + } + + exits.put(dir, r); + } + + /** + * Define the exits of this room. Every direction either leads to another + * room or is null (no exit there). + */ + public void setExits(Room north, Room east, Room south, Room west, Room up, Room down) { + if (north != null) + exits.put("north", north); + if (east != null) + exits.put("east", east); + if (south != null) + exits.put("south", south); + if (west != null) + exits.put("west", west); + if (up != null) + exits.put("up", up); + if (up != null) + exits.put("down", down); + + } + + /** + * Return the description of the room (the one that was defined in the + * constructor). + */ + public String shortDescription() { + return "Room: " + roomName + "\n\n" + description; + } + + /** + * Return a long description of this room, on the form: You are in the + * kitchen. Exits: north west + */ + public String longDescription() { + + return "Room: " + roomName + "\n\n" + description + "\n" + exitString(); + } + + /** + * Return a string describing the room's exits, for example "Exits: north + * west ". + */ + private String exitString() { + String returnString = "Exits:"; + Set keys = exits.keySet(); + for (Iterator iter = keys.iterator(); iter.hasNext();) + returnString += " " + iter.next(); + return returnString; + } + + /** + * Return the room that is reached if we go from this room in direction + * "direction". If there is no room in that direction, return null. + */ + public Room nextRoom(String direction) { + return (Room) exits.get(direction); + } + + public String getRoomName() { + return roomName; + } + + public void setRoomName(String roomName) { + this.roomName = roomName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/com/bayviewglen/zork/Zork.java b/src/com/bayviewglen/zork/Zork.java new file mode 100644 index 0000000..646914d --- /dev/null +++ b/src/com/bayviewglen/zork/Zork.java @@ -0,0 +1,8 @@ +package com.bayviewglen.zork; + +public class Zork { + public static void main(String[] args) { + Game game = new Game(); + game.play(); + } +} \ No newline at end of file