Introduction to Computer Science II by James Tam Return to the course web page

CPSC 233: Assignment 4

New concepts to be applied for the assignment

  1. Object-Oriented design
  2. Solving a moderately sized problem using Object-Oriented decomposition
  3. Using random number generators
  4. Relationships between classes and message passing

Introduction

You are to implement a simple computer game. A party of friends decided that it would a good idea to go camping in the greenwood ignoring all the rumors that these woods were haunted. Now they are stuck out in the middle of no where and must get to the exit before their time (courage) runs out. Magic tokens (which sap the courage of the friends) are randomly created by the "Evil Entity" that haunts the woods. The horrors of wood may be too much for anyone, so the friends may eventually panic and randomly run off (into further danger or blunder blindly into the exit if you're really lucky!)

Classes to implement

At a minimum your program must include or implement the following classes: CommandProcessor, Escape, Forest, ForestItem, GameStatus, Mode.

CommandProcessor: the player's interface with the program. Displays information from the program, gets input from the user.

Minimum required attributes: a reference to an instance of class Forest called 'greenwood'. Something to store user inputs for the main (movement) and cheat menu are likely attributes.

Minimum required behaviors: Show the move and cheat menus, get the players input for each of the menus, determine what option was selected by the player for each menu, the ability to call methods of other classes (the last is more a hint of how you will implement this class rather than a requirement for a specific method to write. Much of this class should be similar to the 'Menu' class in the List examples). Finally the main program loop (runs until the player quits, wins or loses the game) will likely be contained in a method of this class.

Escape: The driver for this program (contains the main method). An instance of class CommandProcessor will likely be instantiated in this method.

Forest: tracks all information about the game world, the haunted forest.

Minimum required attributes: a reference (called 'grid') to a 10x10 array of references to 'ForestItem', a constant (called 'size') that specifies the size of the array. Empty elements should be set to null. Occupied elements will be a reference to a ForestItem object whose appearance is 'P' (player's party), 'x' (Tokens that decrease the player's courage), or 'E' (the exit).

Minimum required behaviors: display the game world (you will get a few extra marks for displaying a numbered grid around each array element), randomly distributing additional tokens, moving the player...in short 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).

ForestItem: the objects that populate the game world. Examples of ForestItem include the player's party, the tokens and the exit. What distinguishes these types of objects is their appearance attribute.

Minimum required attributes: a character to store the appearance and an integer that tracks the courage of the item. The party will having a starting courage of 100 which will be decreased as the game progresses or when it's near a token. All other entities will have courage set to zero and their courage won't change over the course of the game. When the party's courage drops below 25 there is a 50% chance that it will enter panic mode during a turn. (This 50% chance is checked each turn after courage is below 25). When the party's courage reaches 0 (or lower) then they have died of fright and the player loses the game.

Minimum required behaviors: changing the courage attribute as needed, implement the require actions when the player's party 'panics'.

GameStatus: It will store information about the state of the game: won, lost or neutral. The game starts in the neutral state and remains that way until the win or lose game conditions have been met. If the player quits the game prematurely then he or she has neither won nor lost. This class must be implemented entirely using static methods and attributes (otherwise multiple objects may have conflicting game statuses). Alternatively you could write a non-static version and instantiate one instance of the class but you would have to ensure enforcement of the singleton design pattern (if you don't know what I'm talking about then just stick to the static version). This class must be implemented in the following fashion:

public class GameStatus
{
     // Publicly accessable constants will be defined for the 3 game states (WON, LOST, NEUTRAL)
    private static int current = <Neutral state by default>

    // A static method that is publicly accessable which updates the status as needed at the end of each turn.
    // This method will determine if the current status changed by examining the state of the greenwood Forest
    // (win game condition) or the state of the player's party in the case of the lose game condition).
    public static void updateStatus (Forest f) { ... }

   // A static method that can be used to query the game state (to be used by the other classes).
   public static int checkStatus () { return current; }
}

Mode: It will be defined as follows:

public class Mode
{
     public static boolean debug = false;
     public static boolean cheat = false;
}

The sole purpose of this class is to determine what mode that the game is operating under. When turned on, Debug mode will result in debugging messages appearing as the program runs. Except for when you implement the code to handle the player's party panicking you can choose whatever you want for the these debugging messages. You do however need to display a specific debugging message when the party is panicking. The player will have the option to change the mode of the program via the 'cheat' menu which can secretly accessed from the main menu by entering the hidden option (number zero).

Program features (you will also be graded on other criteria such as style and documentation as listed in the marking key): 

 
  1. Displays an introduction to the program that describes the rules of the game. It only displays these instructions right after the program is run.
 
  1. Displays a sign off exit message when the program ends (when the lose and win game conditions have been implemented it should also display a message that is appropriate for the state of the game).
 
  1. Displays the main menu. This menu shows the movement options available to the player. The party can only move to an adjacent and empty square [Example of adjacency] (or the square containing the exit). The destination cannot be outside the bounds of the array. Options are mapped to numeric keypad (North/up = 8, West/left = 4, East/right = 6, South/down = 2, the 4 inter-cardinal compass directions are mapped to 1, 3, 7, 9, entering 5 means that the player doesn't wish to move). Entering a negative value will exit the game. Entering zero will invoke the hidden option to display the 'cheat' menu.
 
  1. Game will continue running (a turn passes) until the player quits, or the win or lose game conditions have been met. See the description [time passing (turns)] for what happens during a turn as well as the order in which things take place in the game.
 
  1. Displays the cheat menu. There should be 3 options: (c)heat mode toggle (d)ebug mode toggle (q)uit the cheat menu (return to the main menu, no cheat invoked). The program will continue prompting the player if a value other than cheat, debug or quit was entered. Entering a valid value will return the player to the main menu. Time will not pass when the cheat menu is invoked. Nor will time pass when invalid values are entered. When the forest is displayed the game will indicate if cheat and debug mode are turned on (but will not display anything special if these modes are turned off).

    Debug mode causes debugging messages to be displayed. Cheat mode will stop the party's courage from going down (although it could panic if courage is low before cheat mode is invoked).

 
  1. Panic mode: When the party's courage is low (below 25) the game checks if the party panics during the term. Each turn that courage is low there is a 50% chance that the party will panic. When this occurs then the player loses the ability to control the party that turn (the main menu will not be displayed) and the party moves randomly:
   

Repeat three times:

Randomly determine which of the adjacent squares [Example of adjacency] that the player is to move onto. In panic mode there is no  chance that the player will remain on their existing square, the party must try to move.

If the destination is empty or contains the exit then the party will move onto it. (The player could conceivably win the game through luck during panic mode).

If the square is out of bounds or occupied then the party won't move. Panicking in debug mode: When in debug mode the program should generate an appropriate error message. This is a specific requirement of debug mode in order to get full credit for the debug mode feature. It's needed so you (and your marker) can easily tell if the party isn't moving because it's trying to move onto an invalid square or if your program erroneously allows the party to not move if in debug mode. Missing these debugging messages will result in a loss of two marks from the credit you receive for panic mode.

The movement during the panic movement does not decrease courage (neither the one point loss due to time passing or the ten point loss when the party is adjacent to a token). Only after the player has finished the random panicked movement will the usual deduction of courage will occur (minus one for the passing of one time unit plus the possibility of an addition deduction if any tokens are adjacent to the player).

The next turn the game will again determine if the player enters panic mode. If panic mode is entered then the above algorithm applies. If panic mode is not entered then the party can be moved as per a normal turn.

 
  1. Tokens will be randomly scattered throughout the array. The simpler version of the game will randomly place 5 tokens in empty squares. A slightly better version will randomly place 5 - 8 tokens in empty squares. If there are no more empty squares then the program will stop placing tokens.
 
  1. Tokens will reduce the party's courage by 10 if they end up in a square that is adjacent to one or more tokens. Being adjacent to more than one token will not decrease the courage by more than 10.
 
  1. The game is lost when the party's courage reaches zero or less. The game should not proceed to the next turn and an appropriate signoff message should be displayed. The lose game state takes precedence over the win game state (if the two events should occur during the same turn).
 
  1. The game is won when the party reaches the exit, which is at location (9,9) in the array.  Again the game should not proceed to the next turn and an appropriate signoff message should be displayed.

Time passing (turns): your program must be implemented in the following fashion

Time passes in discrete units of time (a turn). The passing of each turn will decrease the party's courage by one. During each turn the following things will occur in the following order:

Resources:

There is a Java executable in the UNIX directory: /home/233/assignments/assignment4. The starting positions can be read from file or hard-coded in the constructor of class Forest. You will get extra marks if your program performs the initialization in the former case.

Reading from file: see the sub-directory called "file_initialization". It contains a file called "File_Forest.class" and a data file called "input.txt". Both of these files must be copied to the directory or folder where the classes for your assignment reside. The class file performs all the file input and output for your program and returns an array of type 'ForestItem' with all the positions read in from file. Empty elements are null references.

Getting positions from a hard-coded constructor: see the sub-directory called "hard_coded_initialization". At a minimum you need to use the constructor of class 'Forest' to get the starting positions of the items in the forest. Again empty elements are null.

For both of  these approaches you also need a minimal definition of class ForestItem not only to declare the array but also because these two initialization methods will require a call to the ForestItem constructor. This constructor will take a character as a parameter and set the appearance field of this class to this parameter. In the hard_coded_initialization directory I've already written a minimalistic class definition which can use for either approach.

See the README file for more detailed instructions on how to use these resources. You can if you wish write the equivalent Java code yourself.

Submitting your work:

  1. Assignments (source code/'dot-java' files) must be electronically submitted according to [the assignment submission requirements].
  2. 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].
  3. Before you submit your assignment here is a [checklist] of items to be used in marking.

External libraries that can be used

  1. Libraries that allow for text-based (console) input and output.
  2. Classes used to generate random values such as Class Random or class Math.

Acknowledgements

 

The common cold virus

 

Spooky Calgary weather (fall 2010)

 

Movie: The Blair Witch Project © Lions Gate Entertainment

No picture

 

Game: Call of Cthulu © Chaosium Inc.

No picture

 

Catch all: most any horror movie that I've watched or horror novel that I've read.

No picture