CMSC 132 -- Project 2

Heroes and Vampires

Project Due: Monday, 2/21/05 at 11:00 PM

UML Diagram Due: in your Lab Session Monday, 2/21/05


Open Policy

This will be the only "open" project this semester.  An "open" project is one where you are free to discuss with your classmates details about how you are implementing specific parts of the program.  However, you must adhere to the following guidelines:


The primary goal of this project is for you to practice designing a fairly complex  project using the principles of Object Oriented programming that you've been learning.  You will decide what classes and interfaces to write and how they will relate to one another.  As you read this project description, begin thinking about ways to organize your program that will eliminate code duplication and would make it easier for someone to understand or possibly modify your code later.  Also, you should plan that the classes you are writing in this project may be used in a completely different project one day.


You will write a program that will simulate an adventure.  A hero (either a Wizard or a Warrior) will enter a dungeon.  As the hero travels from one room to another he will do battle with numerous vampires.  The program terminates when the hero is killed.


To give you an idea of what the finished product will look like, here are the outputs from a few runs of the program that you will write.  (Actually, these are the outputs from the five public tests that you will be given.)


Your output will be sent to the standard output stream using System.out.  In order for us to automatically grade your project, your output must match ours exactly.  It is okay if you capitalize where we haven't (and vice versa), and it is also okay if you have extra or fewer spaces between words (or extra or fewer blank lines).  However:  you must spell words exactly as we have, you must punctuate exactly as we have, and you may not insert spaces where we have none.  Check your output carefully!  The public test cases that we have provided should help you to verify that your output is formatted correctly.

Please do not correct grammatical errors generated by the output specifications we have provided.  For example, the first room will always contain "1 vampires" and that first vampire always has "1 hit points".  Please do not report us to the English Department.

Any dungeon historian will tell you that it makes perfect sense to have an "enchanted enchanted sword" or a "cursed enchanted cursed cursed potion", so please don't be concerned if such descriptions occur in your output sometimes!

Overview of Project Components

Here we give a brief description of the project components.  Details about how to implement behaviors will come later.


Items are things that can be carried.  Every item has a description (a String) and a monetary value (an int).

Life Forms

This project involves various life forms.  Every life form has a certain number of hit points (an int).  As life forms are damaged, their hit point count decreases -- if it goes to 0 (or negative) then the life form has died.  Every life form carries exactly one item with him at all times.

All life forms are able to:

Some life forms are capable of spell casting.  How these capabilities are implemented depends on the kind of life form who is casting the spells.  Life forms who cast spells are able to:

Some life forms are capable of physical fighting.  How these capabilities are implemented depends on the kind of life form who is physically fighting.  Life forms who physically fight are able to:

There are two kinds of life forms in this project:  heroes (the good guys) and vampires (the bad guys).


Vampires are life forms that are capable of both physical fighting and spell casting.  Scary!

Heroes (Wizards and Warriors)

Every Hero has a name (a String).  There are two kinds of heroes:  warriors and wizards.  Warriors are capable of physical fighting but not spell casting.  Wizards are capable of spell casting but not physical fighting.

Okay, Start Planning!

At this point you should start giving serious thought to how the classes and/or interfaces in your project will be organized.  Try to sketch out a preliminary UML class diagram.

The Dungeon Class (Program Overview)

For this project, you are expected to write many different classes and/or interfaces of your choosing, but we are going to insist that you write one particular class:  Dungeon.  The Dungeon class must have a main method.  This is the method that the user will call to "run" the program.

The user will pass exactly 5 arguments to main.  These arguments describe the hero who will be entering the dungeon.  You will see that the outcome of the adventure is completely determined by the arguments that are provided.  (Nothing is random.)  A typical set of arguments might look like this:

Wizard Gandalf 80 Staff 17

When the program starts, a message is displayed that says "<heroName> enters the dungeon".

The hero will go from one room to the next fighting vampires until he has been killed.  (See the example run called output5.txt for the precise formatting of output as the hero moves from one room to another.)  Each room contains more vampires than the last, and each vampire is harder to kill than the last.  The first room contains 1 vampire, the second room contains 2 vampires, then 3, etc.  The first vampire in the adventure will have 1 hit point, the second vampire in the adventure will have 2 hit points, then 3, etc.  Since all life forms carry an item with them at all times, we must specify what items the vampires will carry when they are created.  The first vampire will carry a "sword", the second will carry a "ruby", the third will carry a "potion", the fourth will carry a "helmet", the fifth will carry a "key".  After that they will continue to cycle through these same five items.  (So the sixth vampire encountered will carry a "sword".)  The monetary value of the vampires' items will continue to increase.  The value of the first vampire's item will be 5, the value of the second vampire's item will be 10, then 15, etc.

The hero will fight one vampire at a time!  [Hint:  Do not bother to create all of the vampires that are in a room at once.  Just create one vampire and then when he is killed create the next one, etc.]

When a battle takes place between a vampire and the hero, the combatants will take turns attacking each other (as described below).  The vampire always goes first.  The battle continues until one of the combatants is dead.  If the hero dies, the message "<heroName> has died" is displayed and the program terminates immediately. [Note: Do not use System.exit to terminate your program! Just use a return statement to terminate the Dungeon.main() method.]  If the vampire dies, the message "the vampire has died" is displayed.  At this point the hero will consider replacing the item he is carrying with the one that the dead vampire is carrying.  If the value of the dead vampire's item is larger than the value of the hero's current item, then the hero will replace his current item with the dead vampire's item.  In that case the message "<heroName> takes the <itemDescription> (value <itemValue>)" is displayed.

If all of the vampires in the room are slain, then the hero moves on to the next room.  (See the example run called output5.txt for details on the output and correct formatting when moving on to the next room.)

How Behaviors are Implemented

The "Magical Aura Grappling Index Coefficient"

According to legend, when two life forms engage in combat, their actions are dictated by what the sages refer to as the "Magical Aura Grappling Index Coefficient", or MAGIC.  MAGIC is an integer from 0 to 16 (inclusive) whose value depends on the precise state of the two combatants.  If you can compute the value of this mystical number just before an attack takes place, you will be able to predict exactly what will transpire during the attack.  (Of course the value must be re-computed for the next attack.)  According to the ancient tomes:

   MAGIC = [ (attacker hit points) + (defender hit points) + (value of item attacker is holding) + (value of item defender is holding) ] % 17

Note:  the percent sign (%) in the formula above is the modulus operator.

Behaviors common to ALL Life Forms

Warrior behavior

* You may wonder why you are being instructed to check if the enemy is capable of spell casting when in this project warriors will only be fighting vampires, whom we know are capable of spell casting.  The answer is that we may want to use your warriors in another project one day where they fight all sorts of other creatures.  (See the "Important Note", below.)

Wizard behavior

* You may wonder why you are being instructed to check if the enemy is capable of physical fighting when in this project wizards will only be fighting vampires, whom we know are physical fighters.  The answer is that we may want to use your wizards in another project one day where they fight all sorts of other creatures.  (See the "Important Note", below.)

Vampire behavior

Important Note

Try to design classes/interfaces that can "stand alone" without the Dungeon class.  In other words, design your classes so that they would work in a completely different scenario.  For example, someone might want to write an application where vampires fight each other, or where a completely new kind of life form is introduced that will interact with the ones you have written.  We want someone to be able to re-use our code in a new application with minimal (if any) changes.

Warning:  Do not use static variables!

If you use static variables for this project you will probably find that you will not pass the test cases.  The reason is that after the first JUnit test runs, the second test begins and the values of the static variables are not re-initialized, even though your program runs again from the beginning.  

Warning:  Do not terminate your program with System.exit()!

System.exit does not terminate your program "gracefully", and it will throw exceptions during our testing, preventing you from passing any of our tests.  

Java Hints

UML Diagram Requirement

In addition to submitting your working program, you will also be required to submit a UML class diagram for your project.  You are not required to include too many details in the diagram -- just show all of the classes and/or interfaces that you are using and the relationships among them.  (You do not need to show state and behaviors -- just the names.)  The UML diagram will account for 10% of your grade on the project.  You must hand in the UML diagram during the lab session on Monday, 2/21.

Test Cases (10)

Public Tests (5)

If you look in the project folder provided, you'll find files named input1.txt, output1.txt, input2.txt, output2.txt, etc.  These files correspond to the five public test cases.  For example, the first public test case will run your program using the contents of the file input1.txt as arguments for main().  The test will verify that your corresponding output looks exactly like the contents of  output1.txt.  If your output doesn't match, you'll fail the test.

Release Tests (5)

Three of the release tests have funny names.  For example, one of them is called testWizard_X_1_Item_8.  The name is giving you an idea of what the test will do.  In this example, your program will be run by passing the following arguments to main():  Wizard X 1 Item 8

There are also two release tests with names that are much less helpful!


Your grade on this project will be calculated as follows:

Web Accessibility