CSCI213
Autumn Session, 2007

Assignment 2: Simple class hierarchies

(You should complete the exercises for laboratory exercise 2 before attempting this assignment.)

Aims

The aims of this assignment are to:

(This is the shortest and simplest CSCI213 assignment. The coding is intentionally very simple. The difficulties, if any, will relate to all the new OO concepts.
You will find integrating code with a framework to be a novel experience; but it is an important one. Most "enterprise computing" is based on this approach. In more advanced "enterprise" programming contexts, such as for example "Servlets" or "Enterprise Java Beans", your development is restricted to creating application-specific component classes that are deployed into supplied frameworks, such as Tomcat or AppServer. The framework code organizes the overall processing, your code must comply with standard interfaces providing defined functionality as used by the framework. Generally, your task is to write specialized subclasses of component classes defined by the framework, as you do in this very simplified assignment.)

Objectives

The assignment involves writing a "Monster" abstract class and a set of subclasses that define specialized monster subclasses that can be used with supplied code for an "adventure" game like "Hack" or "Rogue".

On completion of this assignment you should be able to:


Framework

Outline

You are supplied with working code for a part of a simple "adventure" game. Most of you will have played such games, or had a sibling that played such games; so lengthy explanations shouldn't be needed. All such games are based on the same simple themes:

If you are a player, you will be using sophisticated massively multiplayer on-line games like Guild Wars, Warcraft, or Everquest, or offline single player games like NeverWinter Nights. But these games date back a long way. If you were playing in the 1970s, you would have played "Colossal Cave" (a single user game), or later "Rogue/Hack". In the 1980s, you could have played "AberMud" (a massively multiplayer on-line game with a text interface).

I didn't have the time to create a Guild Wars like framework, and you don't have the time to learn about such a framework. So the adventure game that you will complete is similar to a late 1980s version of Rogue (Hack, ...) with a simple graphical interface. By default, the game will appear something like the image shown here:

Screenshot

The display shows the (fixed) layout of the dungeon with walls:

Wall

that limit most movements. (The dungeon is defined via a grid of squares - a square may contain a wall or be an open square. An open square can hold one item - treasure, player, monster. Actually, as coded, a grid square can hold many treasures and monsters but only one will be displayed.)
The player avatar is (currently) represented by this image

Our hero

(an alternative hero image may be used if this one is felt inappropriate). The image

Money

represents one of the treasures.
The image:

Inhabitant

represents one of the inhabitants of the dungeon.

The player controls movements of the avatar using the number keys - "8" moves the avatar up screen, "4" moves left, "3" moves diagonally down and right etc. The player acquires treasure items by causing the avatar to move to the same location; the player can attack a "monster" by moving the avatar to an adjacent location and then trying to move onto the monster's location.

The code that you are supplied with works. However, the dungeon has been depopulated. The classes that define the "Monster" abstraction and the concreter monster subclasses have all been removed.


Framework classes

The framework code supplied can be used essentially unchanged. Your changes (details below) can be limited to adding the names of a few more image files to the list of images of game elements (you will need images to represent instances of your different monster subclasses), and adding code that loads data defining the abilities and starting locations of individual monsters. The code for working with a collection of Monsters is already incorporated in the supplied code.
Your main work will be the definition of an abstract Monster class (that extends one of the classes supplied) and concrete subclasses. The code of the "Player" class that is supplied gives examples of how to move around the dungeon and interact with dungeon items.
Once you have completed the specified requirements of the assignment you may make further changes in the supplied framework code to enhance your own version.

The framework is supplied as a NetBeans project (in /share/cs-pub/csci213/A2). The files include a few images, a data file, and the source code files for the classes provided.

The classes in the framework are:

JavaDoc documentation is available for the classes.

The following diagram shows the form of the class hierarchy for the game:

Class hierarchy

Object stuff! Polymorphism, dynamic dispatch, heterogeneous collections!!!

The following code fragment is from the DungeonGame class:

	private void showInhabitants()
	{
		for(Monster m: myCollectionOfInhabitants)
			m.show();
	}


The DungeonGame has a private data member:

	private Vector<Monster>	myCollectionOfInhabitants;

This is filled with Monster objects as these get read in the loadItems function called at startup. Of course, there are no instance of class Monster - it is an abstraction; instead there are instances of Monster subclasses ("Ghost", "Zombie", "Mugger", ...). The collection is heterogeneous (containing different types). In the showInhabitants function, the object reference variable m is polymorphic - referencing many different shaped objects. The dynamic dispatch mechanism would be invoked - though in this case all Monster classes will use the same implementation of show as defined in the base class DungeonItem.

private void moveInhabitants()
	{
		for(Monster m : myCollectionOfInhabitants) 
			m.run();
	}

The moveInhabitants function works through the collection of Monsters giving each its chance to do something. The "run" function that gets invoked here is probably the same and would be defined in abstract class Monster for it is this function that defines that common behaviour - if can attack then attack else if can detect then advance else carry on. However, the functions that define "can attack", "can detect" would be abstract in class Monster having distinct definitions in the Monster subclasses. So the functions that are invoked when run is called are specific to the type of object that is executing the run function. This is the dynamic dispatch behaviour - invoking the right behaviour for the particular object accessed via the polymorphic reference Monster m.


Task

You should be able to deploy the supplied NetBeans project and run the application. When the dungeon map is displayed, click on it with the mouse (to assign "keyboard focus"), then use numeric keys to move the player avatar. The "treasures" can be collected; when all are collected the program will terminate.

The layout of the dungeon and location of treasures is defined in the data2.txt file in the project folder.

Read the code of Images.java to see where you will have to define additional data elements for other images. Read the code of DungeonGame.loadItems to see where you will have to define additional code for loading data on monsters. Read the code of Player.java to get some ideas of how the framework code works.

Define abstract class Monster extends ActiveItem. You will have to define a run method and some other abstract methods. (You may find that you need to redefine your Monster class a couple of times as you explore different ways of factoring out code that is common to specific subclasses of class Monster).

Define at least four distinct concrete subclasses of Monster that illustrate different implementations of the "can attack", "can detect", "attack", "advance", and "go about normal business" functions. You should be able to draw on your own experience of such games for ideas as to different behaviours. However, here are some suggestions for those who have never played:

Do not create subclasses that differ only parametrically. For example, the following would count as a single class:

(It was OK for the Perl guys with their Animals, but here you have to do things properly!)

When there are only parametric differences, you use the same class. This is illustrated by the code and data supplied. The data include "GOLD" and "HEALTH" objects - but these are both just Collectable objects that differ merely in the image used and the values in other fields.

Add some tracer statements to your classes (and to framework classes if that is more appropriate) so that interactions between player avatar and monsters is logged.

Implement your Monster subclasses, add data to the "data2.txt" data file defining instances of your classes, run the game with an inhabited dungeon.


You will have to read the JavaDoc descriptions to find out all the functions in Player, DungeonGame etc that you may want to use. JavaDoc only documents public functions. You shouldn't need to bother about the private functions; you would only be concerned with these if you were reworking the entire framework to add features (such as Monsters that can move treasures around).

All Monster objects are given a reference to the DungeonGame object in their constructor. One of the methods of class DungeonGame returns a reference to the Player object. One of the methods of a Player object returns its current location (this method inheritted from the DungeonItem base class). So, using a couple of method calls, a Monster object can find the current location of the player's avatar.

The DungeonGame class has a utitility method clearLineOfSight; this determines whether there is a clear line of sight between two points (no intervening walls) and also fills in a supplied array with the points along such a line if one exists. A Monster could use that function to determine whether it could "see" the player. Of course, some types of monster might sense the player in some other way and have a "canSee" function that did not require a clear line of sight, instead relying simply on distance between Monster and Player locations.

The Map provides functions like accessible that a Monster could use to determine whether it could move to a particular square.

How you use these and other functions depends on the behaviours that you wish to define for your Monster classes.


Submission

You are to submit a PDF formatted report file. This report file (prepared in a word processor such as Word and "printed" to PDF file) should contain:

  1. Listings of the Java code for your classes - Monster and its subclasses, modified sections of Images class, modified loadItems function (do not include unmodified code)
  2. Brief commentaries on each of your Monster subclasses explaining their unique approaches to solving the thieving avatar problem.
  3. Screen shots of your program in use and a listing of the data file used to create dungeon as shown in your display
  4. A listing of the tracer statements from your program showing some avatar-monster interactions.
  5. Listings of other changes that you chose to make to the framework code.
  6. Displays of JavaDoc documentation that you compose for your Monster abstract class and its subclasses. (JavaDoc HTML documentation uses HTML "framesets"; Word, and probably most other word-processor programs, will not let you merge frameset-style HTML documents into your main report document. The easiest way of including the JavaDoc in your report is probably to grab screen shots showing the documentation in a browser and paste these into the report.)

The due date for submission will be announced in lectures; the date will probably be around the end of week 6 of session (currently set for April 6th).

turnin -c csci213 -a 2  A2.pdf

Reminders as before

  1. turnin isn't chatty you don't get email back
  2. you can check that your submitted file is safely submitted via turnout program.
  3. turnin only works if you are logged in to banshee - use ssh if you are on a different machine or workstation. (If turnin complains that it doesn't know about the assignment, you aren't logged in on banshee!)
  4. Late turnin will work, you don't need to ask. Late turnin will be valid till midnight on the following Monday at a cost in marks.
  5. Medicals submitted through official university SOLS channels cancel late penalty marks