Due: Friday, 11 Nov 2005 by 10 a.m.
This assignment will give you more practice implementing your own classes. To give you a sense for the process of writing slightly larger programs, we continue to build toward a simple text adventure game. In this assignment you will create a Room class which represents a room in the game. A room may (or may not) contain a monster to fight and a weapon to pick up, and may have exits to other rooms in the north, south, east, and west directions. The player can move among rooms by typing commands such as "north" or simply "n". The player can also attack a monster, get a weapon, look around, or quit the game by typing the appropriate commands. To simplify and compartmentalize the handling of user input, you will use the Parser from lab 9 class which processes or parses each string that the user types, and returns an integer representing a single action from a short list of possible user actions.
Of course, you will reuse the Creature class that you developed in the last assignment (Homework J6) to represent the monsters that the player can fight. You will also extend the Creature class by adding a single private variable and accessor/mutator functions to indicate whether the monster will attack on sight. If you were not able to complete that assignment, or suspect that your code might have bugs, we provide a Creature.class file that you may use instead (with no penalty to your grade) -- this file (Creature.class) needs to be saved to the same directory that your Room.java file is in. We also provide a Weapon.class file in case you did not get that working; again this must be in the same directory as the Room.java file.
The Room class needs to be in a Room.java file. We are not providing a skeleton file.
The Creature class should be extended by adding a boolean instance variable and accessor/mutator methods getAngry() and setAngry(). This variable should always be false by default (you do not need to add a specific constructor that can change its initial value). In addition, the takeDamage() method should be extended to print "<creature name> is down to <creature hit points> hit points" after applying the damage.
The parser class is from lab 9. If you did not complete lab 9, you can use a pre-compiled version here -- this file (Parser.class) needs to be saved to the same directory that your Room.java file is in.
The Room class implements most of the actual game functionality. The Room class should provide the following instance variables:
Room roomToNorth: contains a reference to the Room object reached by going north from this room, or null if no such Room exists.
Room roomToEast: contains a reference to the Room object reached by going east from this room, or null if no such Room exists.
Room roomToSouth: contains a reference to the Room object reached by going south from this room, or null if no such Room exists.
Room roomToWest: contains a reference to the Room object reached by going west from this room, or null if no such Room exists.
String description: a String containing a textual description of the room, e.g. "This is the kitchen."
Creature monster: a reference to the Creature object inhabiting this room, or null if the room is empty of monsters.
Weapon item: a reference to the Weapon object in this room, or null if the room has no weapon lying in it.
The Room class should provide the following methods:
get/set pairs of accessor/mutator methods for all the above fields.
Room(): A default constructor that sets description to "A nondescript room." and monster and item to null.
Room(String desc): A specific constructor that sets description to desc and monster and item to null.
Room(String desc, Creature occupant, Weapon weap): a specific constructor that sets the description, monster, and item fields.
void printDescription(): This method prints description to System.out, then prints a line describing the exits of the room. This line should take the form, "You may exit to the north" or "You may exit to the east, south, and west". If a room has no exits the line should read, "There are no exits". If there is a weapon or a creature in the room, it should print these out as well. Note that you are welcome to print the exits on separate lines (one line says, "There is an exit to the north", the next line says, "there is an exit to the south", etc.)
Room enterRoom(Creature player): This method is called when the player enters a room, and handles all user input and actions until the player leaves that room (at which point enterRoom() returns a reference to the Room object that the player enters next) or quits (at which point enterRoom() returns null). The method should first call printDescription() to describe the room to the user, then enter a while loop that repeatedly:
Calls Parser.parse() to process the next line from the keyboard.
Uses a switch statement on the result of parse() to run the appropriate code for the action that the user typed. Note that these values are all defined in the Parser class, so you need to call them Parser.NORTH instead of NORTH.
Parser.NORTH: Check to see if the roomToNorth field is null. If so, print "There is no exit to the north". Otherwise, print "You walk to the north" and return roomToNorth as the return value from this method. Note that you are not returning a new Room object -- you are returning the value of the roomToNorth.
Similarly for Parser.EAST, Parser.SOUTH, and Parser.WEST.
Parser.LOOK: calls printDescription() to describe the room again.
Parser.GET: Check to see if the item field is null. If so, print "There is nothing to get". Otherwise:
If the player does not already have a weapon (i.e., player.getWeapon.getName() is "bare hands"), then set the player.weapon field to the weapon in this room, and set the weapon in this room to null. Print a message like "You pick up the <weapon name>". Note that when a monster is initially created, it has a default weapon ("bare hands") created.
If the player is already holding a weapon (other than the default "bare hands" weapon) then the player should "drop" it first (i.e., swap the reference stored in player.weapon with that stored in this.weapon and print out an appropriate message). In other words, the this.weapon field should be set to the contents of player.weapon, and vice-versa. You will need to use a temporary Weapon variable to perform this swap.
Parser.ATTACK: Check to see if the monster field is null. If so, print "There is nothing to attack". Otherwise, have the player try to attack the monster using the various methods in the Creature class (e.g., tryToAttack(), takeDamage(), constructHitString(), etc.) -- see the CombatSimulation.java from HW J6 for an example of how to do this.. Whether or not the attack succeeds in causing damage, set the monster's Angry field to true to indicate that the monster will now attack the player. If the monster is no longer alive after the attack, print a message to indicate that the player is victorious and set the monster field to null.
Parser.QUIT: return null from the enterRoom() method.
Checks whether the monster is angry (i.e., monster.getAngry() == true) and if so, has the monster attack the player. If the player is no longer alive after the attack, print a message such as "You died." and return null.
Notice that unlike the CombatSimulation class of the prior homework, the combat is not carried through to completion when the user types "attack". Instead the combat happens one round at a time, requiring the player to type "attack" every turn if they want to keep attacking, but also allowing the player to leave the room if combat is going badly. Once a monster is angry, however, it will continue attacking the player as long as the player is in the same room as the monster.
We provide this class in the Game.java file. The Game class provides the main() method for the game program, which sets up several Room, Creature, and Weapon objects (including the Creature object that represents the player), prints out an introduction, and enters a loop that repeatedly calls the enterRoom() method of the Room object in which the player is located. Below is a map of the "world" that the Game class creates.
You do not need to modify or submit Game.java.
When you are finished, submit just your Room.java file.