CPSC 219: Assignment 6
New concepts to be applied for the assignment1
- Inheritance
- Casting within an inheritance hierarchy
- Method overriding & Polymorphism
[JT's hint: The final exam will include a question or questions
relating to material in the 'hierarchy' section. The question(s) be drawn
from the three new concepts introduced in this assignment (and likely
other topics such as implementing interfaces). Consequently I strongly
recommend that if you don't have time to attempt all the major features of
the assignment that you at least attempt features that require the
application of all of the above topics.]
Introduction
For this assignment you will be creating a computer game that simulates a
portion of Professor JRR Tolken's novel, "The Fellowship of the Ring" (see
Figure 1).
|
Figure 1: Breaking of the
Fellowship (Boromir defends the Hobbits) |
The Gondorian hero Boromir 'B' must
ensure that the hobbits 'h' escape from
the horde of evil orcs: goblins 'g' and
elite Uruk-hai 'U'. The hobbits will
automatically flee to the exit 'X' while
Bomomir is controlled by the player. The orcs will be controlled by the
computer and use their scimitar swords to attack Boromir or the hobbits if
they come within striking range. In addition to scimitars the Uruk-Hai carry
bows and can hit targets from afar. If the players have bought enough time
for the hobbits reach the exit (bottom right) then the game is won (even if Bomomir is
slain). If the hobbits are slain the game is lost. The hobbits may be
physically weak but they can blend into terrain "hide in shadows" so half of
the attacks will miss. Time is broken down into discrete time units "turns'
and each turn is broken into steps or 'sub-turns'. In order to make your
program easier to mark your program must react in a predictable fashion so
the order of the sub-turns must be same as the ones specified in the
"Sub-steps" section.
Required classes for this program
Pre-created
classes that you must use (see the 'resources'
section) |
Classes that you
must implement |
MEObject |
Lotr |
Coordinate |
CommandProcessor |
Humanoid |
MEWorld |
Mode |
Hobbit |
FileMEWorld (class file) |
Human |
|
Goblin |
|
UrukHai |
Pre-created classes
MEObject: represents all the entities in the game world. Much
like the previous assignment's Runner each instance of the class will have an
appearance attribute. Also each MEObject will have a 'hitPoints'
attribute that indicates the amount of damage that the entity can take
before being slain (destroyed for the non-living objects). This class will have a number of class constants: one
for the appearance, one for the default hit points and one to determine
the threshold of life (at or below this level the entity is longer
living). Each child class should have its own class constant to indicate
the default appearance of the instances of that class e.g.,
class UrukHai { public static final
DEFAULT_APPEARANCE = 'U'; ... }
Coordinate: each location (array element) in the world can be
described by a row/column pair. Although I could have required you use a
pair of integers to describe the location it would be easier for this
assignment to use a single object. Some methods will generate and return a
location (e.g., class Humanoid's move
method) so it's easier to return the row and column value as a single
coordinate rather than as two separate integer values. (Recall that
methods only return a single value).
Humanoid: a child class of MEObject,
it represents living and moving occupants of the world. Consequently
instances of this class will have four attributes: the current row/column
coordinate of the humanoid, the attack range, and a boolean flag that
indicates whether the object has moved yet during the turn. Additionally
Humanoids have methods that allow them to move (randomly generates a value
that determines which of the adjacent squares that it will attempt to move
to - the MEWorld class will determine whether that location is a valid: is it in bounds and is it empty).
Finally humanoids can attack one opponent each turn. The default damage is
2 points although the child classes will inflict differing amounts of
damage by overriding the attack method.
Mode: a class used to track the game's state: (1) debug: will
debugging messages appear (2) cheat: is cheat mode enabled (Boromir but not
the hobbits) becomes invulnerable (3) status of the game: is it neutral or has the player won or
lost. The game can only have one state so the attributes and methods are
entirely static.
FileMEWorld: This static class will allow your program to read the
starting positions from an input file called "input.txt".
It will read text the information from the file and depending upon the
character that it encounters it will instantiate the appropriate
MEObject in the array attribute of MEWorld.
To use the code in this class file however you need to make certain that you
follow all design requirements (e.g., classes must implement a constructor
with a precisely defined method signature): <space>
= sets the array element to null, <h>
creates an instance of class Hobbit, <g>
creates an instances of class Goblin, <U>
creates an instance of class UrukHai, <X>
creates an instance of class MEObject and set the appearance field to 'X'. The
static method of this class 'fileRead' will
therefore return a reference to an array of type MEObject with the array
elements initialized with the starting positions specified in the input file.
Your program must have the same starting positions as the ones specified in
the input file shown in the assignment directory.
Classes that you must implement
Lotr: the starting execution point and it should contain a reference
to an instance of class CommandProcessor so that the game can be started:
public class Lotr
{
public static void main (String [] args)
{
CommandProcessor anInterface = new
ComandProcessor ();
anInterface.run();
}
}
CommandProcessor: much like the previous assignment this class acts as
the user's interface to the game.
Minimum required attributes: a reference to an instance of class MEWorld (the
game world), something to store the user's selection for the main and cheat menu
and a boolean flag to determine whether the game is finished/done.
Minimum required methods: will include everything associated with the user
interface (e.g., displaying menus, getting user selections, determining what
selection was made etc. It should also be responsible for starting and ending
the game).
MEWorld: tracks all information about the game world, Middle Earth.
Minimum required attributes: a reference (called 'grid')
to a 10x10 array of references to 'MEObject',
several constants for the array (MIN = index
of first element in a row/column, MAX = index
of last element in a row/column, SIZE = size
of the array). Empty elements should be set to null. Occupied elements
will be a reference to an MEObject object
(or a child class).
Minimum required behaviors: display the game world (you will get a few
extra marks for displaying a numbered grid around each array element),
moving the entities in the game (JT's hint: each entity has attributes so
when you move a life form around you should not just create a new life form at
the destination because the new object's attributes starting attributes may
not be the same as the current values of the attributes of the entity being
moved)...in short the methods include anything
that changes the data of the game world (the grid). Note: the constructor for
this class will determine the starting positions for the objects in the game
world. Consequently it must either read this information from file or
implement the hard-coded approach (see the "Resources"
section of this assignment for additional details).
Hobbit: one of the heroes in the game but is controlled by the
computer.
Minimum required attributes: several constants will be included to model the
hobbits behavior: HIDE_TERRAIN (the
percentage chance that a particular attack on the hobbit will miss),
MAX_HIT_POINTS (hobbits may not be strong but
they are tougher than the average humanoid so they have a higher default value),
EAST/SOUTH (indicates which direction that
the hobbit will travel).
Minimum required behaviors: include some overridden methods. There should be
a new attack method to reflect the range of damage that a hobbit can inflict (1
- 6 points). Also this class should have a new method of deducting damage that
determines whether or not the hobbits take damage from a particular attack.
Human: the hero in the game that is controlled by the player.
Minimum required attributes: a constant
MAX_HIT_POINTS (humans are physically larger and stronger than many of
the other inhabitants of Middle Earth so this value is set higher).
Minimum required behaviors: an overridden attack method to reflect the range
of damage that a human can inflict (4 - 13) points.
Goblin: the weakest of the orc-kind. Humanoids that are villains that
are controlled by the computer.
Minimum required behaviors: an overridden attack method to reflect the range
of damage that a goblin can inflict (1 - 8 points)
UrukHai: the elite shock troopers in the orc ranks. Humanoids that are
the other villains that re controlled by the computer.
Minimum required attributes: a constant to reflect their increased size and
fighting skill MAX_HIT_POINTS, and another
constant DEFAULT
RANGE to reflect the fact that they
carry bows and can damage opponents up to two units distant (up or down two
rows, over two columns).
Minimum required behaviors: similar to class Goblin there should be an
overridden attack method to reflect the range of damage that an UrukHai can
inflict (3 - 9 points).
Providing an overview of your program's classes and their relationships
You will need to create a UML class diagram that specifies the full
information about the classes in your program (method signature and return
value, method attributes) as well as the relationships between classes. Your
diagram should not only include the classes that you implement yourself but
also the required classes that I created.
Program features (you will also be graded on other criteria such as
style and documentation as listed in the marking key): After creating the
above class definitions here are features that should be included in a
working program.
Note: the marking key for this assignment will be set up so you can get a
top grade without necessarily implementing each and every feature (there
will be a margin of error built in). However in order to prepare yourself
for the exam make sure you attempt (better yet complete) as many features as
possible.
- Displays an introduction to the program that describes the
rules. It only displays these instructions right after the
program is run.
|
- Displays a sign off exit message when the program ends.
|
- Starting positions for the objects are initialized in the same
positions as my program. The game world is an array that is an
attribute of MEWorld. The contents of the array will be
initialized using one of two approaches.
|
|
- Hard-coded/fixed positions: the positions are set using the
constructor in the outline 'MEWorld.java'
program included in the assignment directory (see the heading
"resources" for how the assignment resources are organized).
|
|
- Positions are read in from file: using the code provided in my
executable class file "FileMEWorld.class".
There will be a README file that explains how to use the code
provided in this class in your program, make sure you read those
instructions and follow the specifications. You will get more
credit if your program is able work using this second approach.
|
- The game world displayed using a numbered grid. The TA's will
show you in tutorial how to display an array of characters using a
numbered grid, keep in mind that for the assignment your array
should be references to MEObjects
not characters. The current turn number will be displayed at the
start of each turn (but not during each
sub-turn unless there is some
additional information to indicate when a new turn has began).
|
- Boromir's and the hobbit's current hit points are displayed
each time that the world is displayed.
|
- The main (move) menu is displayed. This menu will show the
player the movement options available for Boromir.
|
|
|
- The player can quit the game by entering a negative value at
the main menu.
|
- During the attack sub-step,
the player is presented with a directional menu similar to the
movement menu. In this case the directions will indicate the
directions of attack rather than movement.
|
- The player can invoke the cheat menu from either the movement
or from the attack menu by entering the hidden '0'
option. When invoked the cheat menu will display options to:
1) toggle debugging mode 2) toggle cheat mode as well as option to
3) quit the cheat menu and return back to the previous menu.
|
|
|
- Debug mode implemented: To get credit for this feature, the
player can toggle debugging messages on/off at the cheat menu and
debugging messages will be displayed during the 'on'
state. The status of cheat mode should be tracked by the
appropriate attribute of class 'Mode'.
In order to get credit for features labeled "Debug must show
feature working" debug mode must show enough information so
that the marker can quickly determine if the feature has been
implemented correctly. You can check with your marker for the
specifics on this but generally you are should show the value of
different variables to demonstrate that the feature works e.g.,
when the hobbits are attacked it would probably be a good idea to
show the following information: hobbit hit points before the
attack, the amount of damage inflicted by a particular attack, an
output message indicating if the hobbit took no damage from the
attack (they remained hidden), hobbit hit points after the attack.
|
- Cheat mode implemented: To get credit for this feature, the
player can toggle this mode from the cheat menu. The status of
cheat mode should be tracked by the appropriate attribute of class
'Mode'. When cheat mode is
turned on, Boromir will become invulnerable to all attacks. When
cheat mode is turned off, Boromir will suffer damage from attacks
as usual. Cheat mode has no effect on the hobbits. (Debug must
show feature working)
|
- Boromir can move. The player can move Boromir in any of 4
cardinal compass directions (S, W, E, N: options on the main menu
2, 4, 6, 8), as well as the 4 inter-cardinal directions (SW,
SE, NW, NE: options on the main menu 1, 3, 7, 9) or have Boromir
remain on the same square (option 5 on the main menu). You will
progressively be awarded more marks as you implement the features
below so that the movement is more refined. (Debug must show
feature working)
|
|
- Boromir moves to any of the 8 adjacent squares.
|
|
- Boromir only moves onto empty squares.
|
|
- List bounds are checked during the move (Boromir won't move
outside the game world).
|
- Hobbits move in the following fashion. They start out just
right of the top left hand corner. (Boromir occupies the corner).
From this position they will move along the top row to the top
right corner. After reaching the corner, the Hobbits will move
straight down the far right column until they reach the bottom
right corner. You will progressively be awarded more marks as you
implement the features below so that the movement is more refined.
(Debug must show feature working)
|
|
- The hobbits can move in the directions described above.
|
|
- Hobbits will only move onto an empty square.
|
- The game is won when the hobbits reach the bottom right corner
of the screen. The program needs to be able to detect when this
has occurred and immediately end the game with a suitable
congratulatory message. (Debug must show feature working)
|
- The game can detect when the game is lost (hobbits slain),
which results in it displaying the world once more and ending with
a suitable consolatory message. (Debug must show feature
working)
|
- The player can get Boromir to attack one of the adjacent orcs
(goblins or Uruk-Hai). During the attack step, the program show a
directional menu that's similar in appearance to the move menu.
You should implement the attack feature by overriding the
attack method of class Humanoid so that humans inflict 4 - 13
points of damage. (Debug must show feature working)
|
- The hobbit will attack one opponent who is in an adjacent
square. If there are multiple opponents then the mechanism for
deciding which opponent gets attacked can either be according to
some fixed pattern or it can random. It's up to you and there
won't be a difference in your mark if your approach is reasonable.
You will progressively be awarded more marks as you implement the
features below so that the movement is more refined. You should
implement the attack feature by overriding the attack method of
class Humanoid so that hobbits inflict 1 - 6 points of damage.
(Debug must show feature working)
|
- The orcs (Uruk Hai and the goblins) will move to an adjacent
square. You will progressively be awarded more marks as you
implement the features below so that the movement is more refined.
To make it simple you can use the following approach for
determining what is the order of movements. Start at the
left hand corner. If there is an orc there move it. Now
based on the current state of the orc work along that row
from left to right moving the ones that haven't moved. The
new location of animals that have moved should be treated as
being occupied to animals that move later (but it's source
will be treated as empty i.e., ones near the top left move
'before' the ones near the bottom right). Then move down to
the next row and again move from left to right. Repeat until
the square at the bottom right has been reached. Although
all movements for all the orcs are all finished before the
world is displayed, the program needs some rules for
determining the order of movement (i.e., you can't have two
moving into the same square during one turn). Consequently
that means that movement is checked from top to bottom, left
to right in order to resolve collision conflicts. (Debug must show feature working)
|
|
- The orcs can move to any of the 8 adjacent squares or stay on
its existing square. In this case the choice of square should be
randomly determined and the chance for each of above 9
possibilities is the same for each case.
|
|
- Orcs only moves onto empty squares. If the program's first
choice for the destination square is occupied then the
program shouldn't immediately stop trying to move the orc it
should at least try a reasonable number of randomly generated
choices before determining that it won't move.
|
|
- List bounds are checked during the move (Orcs won't move
outside the game world).
|
- Goblins will attack one opponent (randomly or
predetermined) that is within range. The attack range for goblins,
same as with hobbits and humans is one so it will only attack
opponents in one of the adjacent squares. You need to override the
attack method of the parent class so that goblins inflict 1 - 8
points of damage per attack. (Debug must show feature working)
|
- Uruk Hai will attack one opponent (randomly or predetermined)
that is within range. You will progressively be awarded more marks
as you implement the features below so that the attack is
more refined. (Debug must show feature working)
|
|
- UrukHai will attack one opponent in one of the 8 adjacent
squares. The attack method needs to be overridden so they inflict
3 - 9 points of damage.
|
|
- Because UrukHai carry bows their attack range is two (e.g., if
an Uruk Hai were on row 4 it could attack opponents from row 2 to
row 6).
|
- Hobbits have the ability to blend into their terrain so that
for each attack there is a 50% chance that the attack will miss. (Debug
must show feature working)
|
- Game detects when Boromir is slain (hit points zero or less).
It should remove Boromir from the game world and no longer display
the menus to the player. (Game runs on 'automatic'). The game
doesn't end until the hobbits reach the exit or are slain. (Debug
must show feature working)
|
- Game detects when the hobbits are slain (hit points zero or
less). It should remove them from the game world. (It is possible
that your game can detect when hobbits are slain but not detect
that the lose game condition has been met so I'm listing them as
two separate but related features). (Debug must show feature
working)
|
- Game detects when a goblin has been vanquished. Again the game
should remove the object from the game world. (Debug must show
feature working)
|
- Game detects when an UrukHai has been vanquished. Again the
game should remove the object from the game world. (Debug must
show feature working)
|
- Additional bonus feature: instead of displaying the
simulation in text, a graphical library (e.g., Java 2D,
QuickDraw is used). The interface itself can still be console
based (i.e., select a menu option via console input) just the output can be
graphical. Your graphics don't have to be fancy (e.g., you can
use different primitives, color and/or text to distinguish the
runners) but the graphical version must clearly
represent the same information as the text-based equivalent
(e.g., don't use rectangles of the same size and appearance for
each MEObject). You won't get a lot of extra marks for
implementing this feature (because graphics isn't a key feature
of this program) and you will either have to be familiar with a
library or be willing to invest the time to learn one on your
own. But I did include this feature in case you wanted to spice
up your program and/or you wanted to increase the probability
that your assignment received a higher grade.
|
- Start of a new turn: display the turn number.
- [ Display the world ]
- Player can move Boromir
- [ Display the world ]
- Player can get Boromir to attack
- [ Display the world ]
- Hobbits move (if the game is won then it should display the state of the
world at this point and end)
- [ Display the world ]
- Hobbits attack
- [ Display the world ]
- Bad guys (goblins and uruk-hai orcs) move
- [ Display the world ]
- Bad guys attack (if game is lost then it should display the state of the
world at this point and end)
- [ Display the world ]
They can be found in the UNIX directory: /home/219/assignments/assignment5.
Within this directory are three sub-directories:
'java_code', 'sample_runs'
and
'data'. The first directory contains the dot-java
files that are needed by your program. The second directory contains text
files that show the output of my solution program under different
situations. Since there is no byte code solution to run for this program you
can look through the output of these files to clarify assignment
requirements. The third directory contains sample input files for the
starting positions. The program that you submit to your TA for marking must
work with the positions specified in the file 'input.txt'
but I have in included other input files that you can use for testing (they
are simplified versions of the main input file that you can use to verify if
a specific part of your program is working).
Submitting your work:
- Assignments (source code/'dot-java' files) must be electronically
submitted according to [the
assignment submission requirements]. Also you need a README text
file that lists which of the features of the assignment you have
completed. If there are any special instructions needed to run your
program, e.g., images needed, the instructions should be included in the
README file and these additional files submitted as well. You are to
electronically submit the README file along with your source code (make
sure you don't forgot to submit all the dot-Java files). There is no
need to compress the files via zip or another program.
- As a reminder, you are not allowed to work in groups for this class.
Copying the work of another student will
be regarded as academic misconduct (cheating). For additional details
about what is and is not okay for this class please refer to the
following [link].
- Before you submit your assignment here is a [checklist] of items to
be used in marking.
External libraries that can be used
- Libraries that allow for text-based (console) input and output.
- Classes used to generate random values such as Class Random or class
Math.
- (If the last feature is implemented). Java libraries that draw
two-dimensional graphics.
The Lord of the Rings trademark is owned by
Tolkien Enterprises.
References to the Trilogy are for education fair use only and are not meant as
a copy write challenge.