/** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main The CaveGame is a Java implementation of the old text based adventure game from long ago. The design was adapted from one in Gamma, Helm, Johnson, Vlissides (The Gang of Four), "Design Patterns: Elements of Reusable Object-Oriented Software", Addison-Wesley, 1997. To really be consistent with the old game we would need a much larger cave system with a hundred or so rooms, and a more "understanding" user interface. The old game just put you near the cave, displayed the "view" as text, and offered no instructions. If you gave a command that it understood, you could proceed. If your command could not be interpreted, nothing would happen. Rooms were never identified precisely; your only clues came from the descriptions. You would have to remember or create your own map of the cave system to find your way around. Sometimes you could not return exactly the way you came. An exit to the east may not enter the west side of the "adjacent room"; the passage might curve. Perhaps, this implementation can evolve to be closer to the original game, or even go beyond it. Jim Bieman September 1999. **/ import java.util.Vector; import java.util.Enumeration; import java.io.*; public class CaveGame { private Cave theCave ; private Player thePlayer; /** Our system-wide internal representation of directions is integers. Here, we convert input string directions into integers. Internally, we use integers 0-9 as directions throughout the program. This is a bit of a cludge, but is simpler for now than creating a Direction class. I use this cludge because Java does not have an enumerated data type. */ private int convertDirection(String input){ char d = input.charAt(0); int theDirection = 9999; switch(d){ case 'n': case 'N': theDirection = 0;break; case 's': case 'S': theDirection = 1;break; case 'e': case 'E': theDirection = 2;break; case 'w': case 'W': theDirection = 3;break; case 'u': case 'U': theDirection = 4;break; case 'd': case 'D': theDirection = 5;break; } return theDirection; } /** choosePickupItem determines the specific item that a player wants to pick up. */ private Item choosePickupItem(Player p, BufferedReader keyB) throws IOException{ Item[] contentsArray = (p.getLoc()).getRoomContents(); String inputString = "prepare"; int theChoice = -1; do { System.out.println("The room has:"); for (int i = 0; i < contentsArray.length ; i++) System.out.println((i+1) + ": " + contentsArray[i].getDesc()); System.out.print("Enter the number of the item to grab: "); inputString = keyB.readLine(); System.out.println('\n'); if (inputString.equals("")) inputString = " "; try { theChoice = Integer.parseInt(inputString); } catch (NumberFormatException e) { System.out.println("Invalid input."); theChoice = -1; } if (theChoice < 0 || theChoice > contentsArray.length) System.out.print("That item is not in the room."); } while (theChoice < 0 || theChoice > contentsArray.length); return contentsArray[theChoice-1]; } /** chooseDropItem determines the specific item that a player wants to drop */ private int chooseDropItem(Player p, BufferedReader keyB) throws IOException{ String inputString = "prepare"; int theChoice = -1; do { System.out.println("You are carrying: " + p.showMyThings() + '\n'); System.out.print("Enter the number of the item to drop: " ); inputString = keyB.readLine(); try {theChoice = Integer.parseInt(inputString);} catch (NumberFormatException e) { System.out.println("Invalid input."); theChoice = -1; } if (theChoice < 0 || theChoice > p.numItemsCarried()) System.out.print("Invalid choice."); } while (theChoice < 0 || theChoice > p.numItemsCarried()); return theChoice; } public void startQuest() throws IOException{ Player thePlayer = new Player(); Cave theCave = new Cave(); Room startRm = theCave.createCave(); thePlayer.setRoom(startRm); /** Create the keyboard to control the game; we only need one */ BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in)); String inputString = "prepare"; /* The main query user, get command, interpret, execute cycle. */ while (inputString.charAt(0)!='q') { System.out.println(thePlayer.look()); System.out.println("You are carrying: " + thePlayer.showMyThings() + '\n'); /* get next move */ int direction = 9; System.out.println("Which way (n,s,e,w,u,d)," + " or grab (g) or toss (t) an item," + " or quit (q)?" + '\n'); inputString = keyboard.readLine(); System.out.println('\n'); if (inputString.equals("")) inputString = " "; char key = inputString.charAt(0); switch (key){ // Go case 'n': case 'N': case 's': case 'S': case 'e': case 'E': case 'w': case 'W': case 'u': case 'U': case 'd': case 'D': direction = convertDirection(inputString); thePlayer.go(direction); break; // Grab Item case 'g': case 'G': if (thePlayer.handsFull()) System.out.println("Your hands are full."); else if ((thePlayer.getLoc()).roomEmpty()) System.out.println("The room is empty."); else { Item itemToGrab = choosePickupItem(thePlayer,keyboard); thePlayer.pickUp(itemToGrab); (thePlayer.getLoc()).removeItem(itemToGrab); } break; // Drop Item case 't': case 'T': if (thePlayer.handsEmpty()) System.out.println("You have nothing to drop."); else { int itemToToss = chooseDropItem(thePlayer,keyboard); thePlayer.drop(itemToToss); } } } } public static void main(String args[]) throws IOException{ System.out.println("Welcome to the Cave Game,\n" + "which is inspired by an old game called adventure.\n" + "Java implementation Copyright (c) 1999 by James M. Bieman\n" ); CaveGame theGame = new CaveGame(); theGame.startQuest(); } } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ /** class Cave: Primary method, createCave, creates the cave system. Its hard-coded, and may eventually be replaced with a more flexible mechanism. Room descriptions are followed by a room identifier, to ease debugging and testing. These would be removed to help confuse the user, which is our ultimate aim. I haven't added all of the room descriptions. They will be done later. */ class Cave { private Room entrance; public Room createCave(){ // The outside: Room outside = new Room(); outside.setDesc( "You're outside, on the edge of a cliff;\n" + " the cave opens straight down (outside)."); // Room 1: Room r1 = new Room(); r1.setDesc( "The darkness is pierced by a bright light overhead.\n" + "There is a narrow, dark passage to the east (r1)." ); // Connect the outside to Room 1: outside.setSide(5,r1); r1.setSide(4,outside); entrance = outside; // Room 2: Room r2 = new Room(); r2.setDesc( "You are in a gloomy oval shaped room with grey walls.\n" + "There is a dim light to the west, and a narrow\n" + "dark hole to the east only about 18 inches high (r2)."); // Room 3: Room r3 = new Room(); r3.setDesc("You really need your flashlight here. \n"+ "There is a wide passage that quickly narrows\n" +"to the west, a bright opening to the east,\n" + "and a deep hole that appears to have no bottom\n" + "in the middle of the room (r3)."); // Connect Rooms 1, 2, & 3: r1.setSide(2,r2); r2.setSide(3,r1); r2.setSide(2,r3); r3.setSide(3,r2); // Room 4: Room r4 = new Room(); r4.setDesc("There is what looks like a giant grizzley bear\n" + "skull in a corner. A passage leads to the west,\n" + "another one to the north, and a slippery route\n" + "goes down steeply (r4)."); // Room 5: Room r5 = new Room(); r5.setDesc("Room r5."); // Room 6: Room r6 = new Room(); r6.setDesc("Room r6."); // Room 7: Room r7 = new Room(); r7.setDesc("Room r7."); // Connect rooms 3, 4, 5, 6, & 7. r3.setSide(2,r4); r3.setSide(5,r5); r4.setSide(3,r3); r4.setSide(5,r7); r5.setSide(4,r3); r5.setSide(2,r6); r6.setSide(3,r5); r7.setSide(4,r4); // Room 8: Room r8 = new Room(); r8.setDesc("Room r8."); // Room 9: Room r9 = new Room(); r9.setDesc("Room r9."); // Room 10: Room r10 = new Room(); r10.setDesc("Room r10."); // Room 11: Room r11 = new Room(); r11.setDesc("Room r11."); Treasure theTreasure = new Treasure(); theTreasure.setDesc("A bag filled with gold bars."); r11.addItem(theTreasure); // Lets connect them: r4.setSide(0,r8); r8.setSide(1,r4); r8.setSide(3,r9); r8.setSide(2,r10); r9.setSide(2,r8); r10.setSide(3,r8); // Create a key and put it in r6: Key theKey = new Key(); theKey.setDesc("A shiny gold key."); r6.addItem(theKey); // We add a door between r10 and r11: Door theDoor = new Door(r10,r11,theKey); r10.setSide(5,theDoor); r11.setSide(4,theDoor); // Now return the entrance: entrance = outside; return entrance; } } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // interface CaveSite interface CaveSite{ void enter(Player p); } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // class Door class Door implements CaveSite { /** In this implementation doors are always locked. A player must have the correct key to get through a door. Doors automatically lock after a player passes through. */ private Key myKey; /** The door's location. */ private CaveSite outSite; private CaveSite inSite; /** We can construct a door at the site. */ Door(CaveSite out, CaveSite in, Key k){ outSite = out; inSite = in; myKey = k; } /** A player will need the correct key to enter. */ public void enter(Player p){ if (p.haveItem(myKey)) { System.out.println("Your key works! The door creaks open,"); System.out.println("and slams behind you after you pass through."); if (p.getLoc() == outSite) inSite.enter(p); else if (p.getLoc() == inSite) outSite.enter(p); } else {System.out.println("You don't have the key for this door!"); System.out.println("Sorry."); } } } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // class Item class Item { private String description; public void setDesc(String d){ description = d; } public String getDesc(){ return description; } } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // class Key. class Key extends Item { } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ class Player { private Room myLoc; private Item[] myThings = new Item[2]; private int itemCount = 0; public void setRoom(Room r){ myLoc = r; } public String look() { return myLoc.getDesc(); } public void go(int direction){ myLoc.exit(direction,this); } public void pickUp(Item i){ if (itemCount < 2) { myThings[itemCount] = i; itemCount++; myLoc.removeItem(i); } } public boolean haveItem(Item itemToFind){ for (int n = 0; n < itemCount ; n++) if (myThings[n] == itemToFind) return true; return false; } public void drop(int itemNum){ if (itemNum > 0 & itemNum <= itemCount){ switch(itemNum){ case 1: { myLoc.addItem(myThings[0]); myThings[0]=myThings[1]; itemCount--; break; } case 2: { myLoc.addItem(myThings[1]); itemCount--; break; } } } } public void setLoc(Room r){myLoc = r;} public Room getLoc(){return myLoc;} public String showMyThings(){ String outString = ""; for (int n = 0; n < itemCount ; n++) outString = outString + Integer.toString(n+1) + ": " + myThings[n].getDesc() + " "; return outString; } public boolean handsFull(){return itemCount==2;} public boolean handsEmpty(){return itemCount==0;} public int numItemsCarried(){return itemCount;} } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // class Room class Room implements CaveSite { private String description; private CaveSite[] side = new CaveSite[6]; private Vector contents = new Vector(); Room() { side[0] = new Wall(); side[1] = new Wall(); side[2] = new Wall(); side[3] = new Wall(); side[4] = new Wall(); side[5] = new Wall(); } public void setDesc(String d){ description = d; } public void setSide(int direction, CaveSite m){ side[direction] = m; } public void addItem(Item theItem){ contents.addElement(theItem); } public void removeItem(Item theItem){ contents.removeElement(theItem); } public boolean roomEmpty(){ return contents.isEmpty(); } public Item[] getRoomContents(){ Item[] contentsArray = new Item[contents.size()]; contents.copyInto(contentsArray); return contentsArray; } public void enter(Player p) { p.setLoc(this); } public void exit(int direction, Player p){ side[direction].enter(p); } public String getDesc(){ Enumeration roomContents = contents.elements(); String contentString = ""; while(roomContents.hasMoreElements()) contentString = contentString + ((Item) roomContents.nextElement()).getDesc() + " "; return description + '\n' + '\n' + "Room Contents: " + contentString + '\n'; } } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // class Treasure class Treasure extends Item { } /** Cave Game Program Code Copyright (c) 1999 James M. Bieman To compile: javac CaveGame.java To run: java CaveGame The main routine is CaveGame.main **/ // class Wall class Wall implements CaveSite { public void enter(Player p) { System.out.println("Ouch! That hurts."); } }