Assignment 3: a text adventure game
Due date: 13th May 2019 at 5pm on BlackBoard.
This assignment is worth 10% of your final grade and has 100 marks in total. (Version 2)
Brief
Text-based adventure games have been around since the 1960s and have a simple interface in which the player types in commands using the keyboard. These commands allow the player to move through and search the gaming environment, pick up objects and fight monsters.
For this assignment you are to individually develop your own fully functional text-based adventure game. You are allowed to repurpose any example or exercise code you have implemented in the lab, assuming you have written the code yourself.
Gameplay
The player explores a maze of rooms picking up weapons to wield against monsters, food and valuables to store in their inventory. The player wins if they find the exit and escape the maze. The player loses the game if their health points reach 0.
The player has health and confidence points which are boosted by eating food or admiring valuables in the inventory. Weapons are used to fight monsters and are stored in the inventory. Chests may be found throughout the maze. Treasure chests contain valuables and are opened with a key and War chests contain weapons and are opened with a lockpick.
As the player moves between rooms, a monster may attack them. The player must battle the monster by wielding a weapon and exchanging attacks until one is defeated. During battle, the player may wield any weapon in their inventory. The player’s confidence and wielded weapon determines their attack strength. A monster’s attacks decrease the health and confidence points of the player, based on the strength of the monster.
The tables below describe the commands available in explore and battle modes.
Explore Mode Commands
Description
When the player enters a room the following events occur:
• A monster may randomly appear (and go to battle mode)
• A description of the room is displayed
door n Opens door labeled n and enter the room
pickup item Pick up an item in room and add to inventory
exit Search room to find exit.
describe
Describes the room, list pickups on the floor and number of doors available
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 1
Admire a valuable pickup in the inventory to increase confidence. admire valuable The valuable may only be used once to increase confidence, but is
not removed from the player’s inventory.
eat food
Eats a food pickup in the inventory to increase health points. Once eaten, the food is removed from the player’s inventory.
mobile
Uses the mobile phone pickup if present in inventory (See note below for ENSE602 students only)
stats Display player health and confidence points and inventory
wield weapon Player wields weapon from inventory for battle
wield fistsoffury Player wields fists of fury (does not appear in inventory)
Opens a treasure or war chest in the inventory using the key or open chest key lockpick. The contents of the chest is placed in the player’s
inventory and both the chest and key removed.
help Displays commands in this mode
quit Ends the game
Battle Mode Commands
Description
attack Attacks the monster in the room using the wielded weapon
wield weapon Player wields weapon from inventory for battle
wield fistsoffury Player wields fists of fury (does not appear in inventory)
help Displays commands in this mode
quit Ends the game
Assignment 3 Supplied Files
1. Assignment3Start.zip is a project archive file containing all starting code
2. classdiagram.pdf is a document containing an informal UML diagram outlining
relationships between classes in the assignment
Assignment 3 Eclipse Project
Step 1: Import the Project
You have been supplied with an archive file Assignment3Start.zip to import into your Eclipse workspace. In Eclipse, go to File -> Import -> Existing Projects into Workspace. Click “Select archive file” and browse to Assignment3Start.zip. Ensure the project is selected in the “Projects” list and click Finish. You should see the gameplay package with three classes: Inventory, ReadWorldDataFile and World. The file folder worlddata contains a text file simpleworld.txt.
Step 2: Implement the Entity Class
Implement the Entity class hierarchy as described in the supplied file classdiagram.pdf. Start by defining the abstract class Entity. Abstract classes are denoted by <<>> on the diagram.
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 2
All entities in the game will need a description and a unique identifier String id. Create the Entity(String) constructor which takes a description and sets the unique identifier with the code:
this.id = this.getClass().getSimpleName();
Add get/set methods for the description. Assume throughout that we will need get and set methods for most instance variables, unless stated otherwise. Add a get method for id. The entities in our game will often exhibit randomized behavior. Write a protected method which returns a random integer between two numbers x and y (exclusive):
return new Random().nextInt(y-x) + x;
Next, write the compareID(String) method, which determines the entity’s id equality to a
given string, ignoring case. Lastly, the toString method should return the entity’s id.
Step 3: Implement the Pickup Subclasses
Pickup is an abstract class (extends the Entity class). It simply contains a constructor to initialize the description.
Pickup is extended by Openers, Openable, Consumable and Wieldable.
• The Opener abstract class, Lockpick and Key subclasses have constructors to initialize their descriptions.
• The Openable class has a boolean locked and also has a Pickup content instance variable. The constructor should set these values (description and content) (locked is initialized to true). It has an abstract method unlockWith (Opener) that should be overridden in WarChest and TreasureChest subclasses.
• Consumable maintains a boolean instance variable to determine if the object has been consumed.
• Valuables is an abstract class extending Consumable that maintains a number representing the object’s value. There are seven subclasses; refer to the class diagram and implement each one, defining an appropriate constructor for each. No new methods or data is needed for these subclasses.
• Food is an abstract class which stores a number representing health points. Refer to the class diagram for the names of the three subclasses extending Food. They do not require any additional methods or data.
• Wieldable is an abstract class which has two integer value instance variables high and low. The hit method returns a random number x such that lo <= x < high (using the random method in Entity class), which represents the strength of the weapon. A constructor should initialize all instance variables. There are three subclasses; refer to the class diagram and implement each one, defining the necessary constructor for each class.
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 3
Step 4: Implement the Character Subclasses
The Character class has
• an instance variable to keep track of health points which should always store a non-
negative number
• a constructor to instantiate all instance variables.
• abstract methods
o protected abstract int dealAttackDamage();
o public abstract int defendAttack(Character enemy);
The Monster subclass of Character
• has integer values storing the probability of the monster appearing in a room and
the amount of damage the Monster can deal in an attack. The constructor initializes
these values and the description.
• overrides the above abstract methods. The dealAttackDamage method returns the
value damage+r, where r is a randomly selected value between 1 and 10. The defendAttack method simulates an incoming attack from an enemy character. The method invokes d = enemy.dealAttackDamage() and reduces the character’s health by d. The value d is returned by the method to report how much damage was dealt to the character.
• has a method boolean appear() to determine whether or not the monster appears in a room. If the monster’s health is 0, false is returned. Otherwise, the monster appears with frequency based on its probability value. A simple way to implement this method would be to pick a random number x between 0 and 101 (exclusive) and return x<=probability.
The Player class has instance variables
• confidence value
• name
• Wieldable weapon
• Inventory inventory
• Potentially other variables as needed
The Player class implements the methods
• dealAttackDamage(), which has a different way of calculating the amount of damage
dealt by the player’s attack. It is based on the formula damage = h + h*c/100, where h is the strength of the user’s weapon (hit() return value) and c the confidence of the player.
• defendAttack(Character enemy), behaves similar to the implementation by Monster. It calculates and returns damage from the enemy’s d = enemy.dealAttackDamage and decreases the player’s health by d. Additionally, the player’s confidence is decreased by d/2.
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 4
The Room class contains instance variables:
• Monster monster
• Inventory pickupsInRoom
• Room[] connecting
• boolean finalRoom
The Room objects maintains a list of Pickup objects present in the room by way of the Inventory class, which maintains an ArrayList (supplied for you in the gameplay package). ArrayList is a dynamic array, in which elements can be added and removed. Room will need the default constructor (which initializes instance variables to null values) and constructor with signature
public Room(String description,Inventory pickupsInRoom, Room[] connectingRooms)
Room objects are constructed by the static readFile method in the ReadWorldDataFile class. Thus constructors, get and set methods must match those used.
Step 5: Reading the World File
Now, we are ready to read the world data from a text file. You already have this code in ReadWorldDataFile, so uncomment it and make sure there are no errors. There is a static boolean variable outputToConsole=true, to output debugging information to the console when reading the text file. You do not need to make any other changes to this file.
Step 6: The World Class
You have been supplied with a mostly empty World class. It has a single main method with code to create World and Player objects and invoke a play(Player) method.
World world = ReadWorldDataFile.simpleWorld();
Player playerOne = new Player("Sir Kendric","Shiny Armour",100,50); world.play(playerOne);
Step 7: The play method
The World class implements the core playable functionality of the text game in the play(Player) method. This method has been provided to you and is essentially a while loop to processes input from the player depending on the current mode: battle or explore. The while loop continues until the game stops: when the player wins, loses or quits the game. You will need to write the code for private methods:
processExploreUserInput() and processBattleUserInput()
which prompts the player for input using a Scanner and processes it according to the
commands available in explore and battle modes respectively (given in the Table).
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 5
The pickup command
Suppose processExploreUserInput reads the text “pickup JEWEL” from the player, storing the input in the variable inputCmd. Parse this string into tokens with the code
String[] tokens = inputCmd.toLowerCase().split(“ “);
Which splits the string across spaces such that tokens = [“pickup”,”jewel”].
The processExploreUserInput compares tokens[0] with the commands possible in the explore mode, using a switch statement. Since the player has invoke the pickup command, perhaps a private pickup() method in the World class is invoked. This method would determine if a Pickup object with an id “jewel” was present in the room’s inventory (pickupsInRoom). If so, it would be removed from the room and placed in the player’s inventory.
The admire command
As another example, suppose the player later types “admire goldbars” in the explore mode prompt and the admire() method is invoked, which carries out the following steps:
1. Determine if goldbars is in the player’s inventory (use Inventory’s select method)
2. If so, then Pickup pickup = player.getInventory().select(id)
3. Use the code (pickup instanceof Valuable) which returns true if pickup
refers to a Valuable object.
4. Since GoldBars is indeed a subclass of Valuable, we cast Valuable valuable =
(Valuable) pickup;
5. Then, we are able to invoke this.player.admire(valuable), which you need to implement In Player class to increase the confidence of the player with the valuable's value if it’s not consumed. (Follow same steps for eat command)
All the other commands are structured similarly.
Step 8: The Mobile Valuable (for ENSE602 students)
The Mobile class extends Valuable and can be admired by the player to gain confidence. Like most people, the player finds it difficult being lost in a maze without access to the internet. Thus, the Mobile gives the player a means to check social media. The supplied sample console output file output3.txt demonstrates the following Mobile command:
?> mobile latestTweet HamillHimself
RT @EmmanuelMacron: Let’s face it: there is not Planet B. https://t.co/vtP2NQYcv9
which returns the most recent tweet posted by Mark Hamill (which happens to be a retweet of an original tweet posted by the President of France).
Week 9’s lab will describe how to use the Twitter API in Java. COMP503 and ENSE502 students also interested in attending this tutorial must email me to register their interest.
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 6
Methodology and Marking Scheme
Criteria:
Grade A Range 100 ≥ x ≥ 80%
Grade B Range
80 > x ≥ 65%
Grade C Range
65 > x ≥ 50%
Grade D Range 50 > x ≥ 0%
Entity Class Hierarchy
30%
All classes present with appropriate structure and method overriding
Some minor issues with hierarchy, constructors
Code not appropriately overridden in classes
Absent classes or functionality or code does not compile
Text Processing
20%
Excellent handling of text and command entries Data structures consistently maintained during gameplay
Minor problems with parsing text data from command line input
Problems handling commands in either gameplay modes
Absent functionality for parsing text or commands or code does not compile
Gameplay
30%
Game is robust and easy to play.
Game is easy to play. Minor issues with improper handling of input
Some aspects of the gameplay are poorly implemented and issues with improper handling of input
Absent functionality or code does not compile
Code Quality: -Whitespace -Naming -Reuse -Modularity
10%
Whitespace is comprehensively consistent. All naming is sensible and meaningful. Code reuse is present. Code is modular. Java project is well organized
Whitespace is comprehensively consistent. Majority of naming is sensible. Code is modular. Java project is reasonably organized
Whitespace is consistent. Code has some modularity. Java project is somewhat organized
Whitespace is inconsistent and hence code is difficult to read. Code is not modular (e.g. very large main method). Or code does not compile. Java project is not well organized.
Standards: Commenting, Submission and Javadoc
10%
Entire codebase has comprehensive Javadoc commenting: tagging, class and method comments. Submission instructions followed.
Majority of the codebase features Javadoc commenting. Majority of methods are commented. Submission instructions followed.
Some Javadoc comments present. Some methods are commented. Submission instructions followed.
No Javadoc comments present. Submission instructions not followed.
Javadoc Commenting
1. Your classes must have commenting of the form:
/**
* Comment describing the class. * @author yourname studentnumber
**/
2. All methods must be commented with appropriate Javadocs metatags. For example:
/**
* A comment to describe the method
* @param a first parameter description
* @param b second parameter description
* @return a description of the returned result * @author kjohnson studentnumber
* */
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 7
Weight:
Authenticity
Remember, it is unacceptable to hand in any code which has previously been submitted for assessment (for any paper, including Programming 2), and all work submitted must be unique and your own!
Submission Instructions
Export your Java project from Eclipse as an archive .zip file before the deadline.
Zip structure and file naming requirements. Please ensure your submission matches the following format: lastname-firstname-studentid.zip
You will receive your marked assignment via Blackboard. Please look over your entire assignment to make sure that it has been marked correctly. If you have any concerns, you must raise them with the lecturer. You have one week to raise any concerns regarding your mark. After that time, your mark cannot be changed.
Do not go to the lecturer because you do not like your mark. Only go if you feel something has been marked incorrectly.
Dr. Kenneth Johnson. Auckland University of Technology. Programing 2 Semester 1 2019 8