|
CSE 143 Summer 2001
Homework 4
Due: Electronic submission by 9:30 pm, Wednesday August
1. Paper receipt and written report due in quiz section on
Thursday August 2.
|
Overview
There is a classic game from the days of Apple II+ named
"Hunt the Wumpus". For this assignment, you will work with a
simple graphics package to implement a version of this game, and while doing so,
gain experience in using and designing class hierarchies. We will provide you with most of the graphics code.
As with all assignments, please read the instructions all the way through
before beginning. Read them once again before you turn in your assignment,
to be sure you've left nothing out.
Concepts
- Review (from CSE142) of basic graphics and event loops
- Inheritance and derived classes
- Virtual function calls and dynamic dispatch
Program Specification
For this assignment, we have provided a small
starter program as well as a modified version of the GP142 graphics package that
has an object-oriented interface (more about all of these files below). When the starter program is executed, it opens a graphic window and displays a
menu. The menu contains entries for starting a new game and quitting .The
goal of Hunt the Wumpus is, as the name implies, to find a creature named
"The Wumpus". The game takes place on a 7x7 checkerboard which
represents a cave. Your character begins in one of these squares. Each
cavern (square) is connected to 4 others by tunnels and the character may move
from her current square to any adjacent square (up, down, left, right). At
the outset only the square which the player is in should be displayed. When
the character enters each new square, it should also be displayed and one of four events will occur:
- The character feels a draft. If you feel a draft then one of the
four adjacent squares contains a pit.
- The character smells a Wumpus. This indicates that one of the four
adjacent square contains the Wumpus.
- The character enters a cavern that holds a Wumpus and is eaten. (Game
Over)
- The character enters a caven that holds a pit and falls in. (Game
Over)
Each turn you can choose to either:
- Move to an adjacent square (up, down, left, right).
- On the keyboard : A - Left, D - Right, W - Up, S - Down
- Fire an arrow into an adjacent square. If an arrow enters a cavern
that holds a Wumpus, he will be hit and you win! However, if
you shoot in the wrong direction the Wumpus will eat you, which will be game
over.
- On the keyboard : J - Fire Left, L - Fire Right, I - Fire Up, K
- Fire Down
- Click on "new game" to start a new board
- Click on "quit" to quit the game
The object is to shoot the Wumpus without getting killed first. (Don't
worry, for all animal activists, we're only shooting the Wumpus with a
tranquilizer dart to capture him and place him in a nice zoo ; )
Implementation Requirements
The key goal of this assignment is to learn
how to build a class hierarchy using inheritance and how to use virtual methods.
Here is the specification of the classes you must implement. Remember, the
list below does not represent all variables and functions you will need in the
program, only the required functionality.
- An abstract class Cavern that defines the interface of a generic
cavern (square) on the board. Cavern should include at least the following members:
- pure virtual method draw that draws the Cavern in the window;
- pure virtual method action that prints (displays) messages to the
player in the bottom right hand corner of the screen or takes other
actions necessary when the player enters that room.
- pure virtual method typeQuery function. This will
return the type of the Cavern (Wumpus, Pit, or Empty)
- Derived classes Wumpus and Pit and Empty
which inherit from Cavern and include appropriate implementations of
Cavern's pure virtual methods.
- When the character enters either the Wumpus room or a Pit room,
the action function should inform the user that the character has
been eaten or fallen respectively. Whether you represent this in
the form of a text message or a graphic is up to you. The player
should also be informed that the game is over. A new game should
be started automatically.
The Empty action function should search the 4
adjacent squares (using the typeQuery function) and if a Wumpus or
Pit room is adjacent then display to the user that the character
smells a Wumpus or feels a draft respectively.
The Empty action function should be void of code except possibly to set a variable indicating that the cavern has been "visited".
- The Wumpus, Pit, and Empty rooms should each have
unique draw functions. How you display them is entirely up
to you. It can be as simple as different colored squares or as
complex as you like.
- A Character class that defines the player. This class
should contain at least the following members:
- Current X,Y position, representing the current location in the game
grid.
- A draw method, which draws the character
- A method for updating x,y values when the character moves.
- A WumpusGame class which contains at least the following members
- An instance of Character
- A 7x7 array of type Cavern * named gameGrid. This
array will represent the game board. NOTE: As we are using virtual
functions this array only contains pointers to Caverns. It will be up to another function to actually allocate the memory for
each element.
- A draw function which updates the game board each turn by
calling the Character and Cavern draw functions. NOTE:
Only squares that the player has already visited should be displayed.
- A newGame function which deallocates memory currently assigned
to the game board, and randomly creates a new game board by allocating
memory to each element of type Empty, Pit, or Wumpus. Note:
There should not be more than one Wumpus in each game. When the
game starts for the very first time, newGame should be
automatically called.
- A shoot method which takes a direction (up, down, left, right).
If the cavern in that direction from the user contains the Wumpus,
inform the player that she has won! Otherwise, inform the user
that the arrow missed and the character was eaten by the wumpus.
This results in a game over, and newGame should be called.
- A move method which appropriately updates the characters
position and calls the appropriate action function.
- A method which searches the 4 adjacent caverns to a player (using the typeQuery method). If any of the adjacent caverns are of type "wumpus" or "pit" then an appropriate message should be displayed (about smelling the wumpus or feeling a draft). This method may be part of the "move" method.
From this assignment on, all concrete classes in your program must provide a
default constructor, and if memory is dynamically allocated, a destructor.
Each dynamically allocated class instance or any other memory you
may allocate dynamically must be deleted properly after you are done using it.
You may not use any global non-constant variables.
Do not modify the GP142 files. Your program should work with the
unmodified GP142 package.
Implementation Hints
Start with planning
As usual, do some planning first. Design your
hierarchy of cavern classes; sketch class declarations.
Download and install the graphics code
Next download and install the
graphics code that we provide for this homework. It includes the GP142
graphics package and the starter code. Download all of the following
files:
If you are using MSVC, create a new project which must be of type
Win32 Application. Then add all the above files to that project. Now
you should be able to compile and run the project as-is.
If you are not using MSVC, you will need to follow the instructions at the
bottom of the GP142 page. Your installation is
successfull if you are able to compile and run the program.
Familiarize yourself with the graphics code
Start by looking at
hw4_starter.cpp. It contains main() that opens a graphic
window, draws a simple menu with three shapes and enters a loop, processing
mouse click events when they occur. Check out the code that draws the shapes
inside draw_shape_menu(). For an explanation and details look at the GP142 page.
Plan the implementation of the required functionality
Given the starter
code, plan what other functions you will need to write and invoke. Only after
you have done all of this should you start coding.
GP142 hints
Note that coordinates are integers, not doubles. Use
int for the type of all coordinate variables.
Writing to cout is not supported. Use the write functions
of the GP142Display class declared in gp142display.h.
Do not pass the GP142Display object by value, only by reference or
alias. If you pass this by value, you will have strange screen refresh
errors.
Other hints
You will need to add code inside the handleKeyPress(...) function to process the
keyboard commands, and
inside main() to process other. These places are marked with a comment. Feel free to modify the existing
code as needed, for example, to pass additional arguments to existing functions,
modify the code in places other than commented, etc.
Hints on generating random numbers can be found here.
As usual, if the specification is not clear, make reasonable assumptions.
Feel free to discuss issues about the specification on the course newsgroup, in
sections, with your colleagues, etc.
Testing
You should run your program to make sure it works properly. Be
sure to test each method that your classes implement; you may need to write some
additional code for that.
Report
Look back at your program and see what you have learned. What did
you find interesting? unexpected? Write a brief report answering these
questions.
Electronic Submission
When you've finished your program, turn in the source program (.cpp and .h
files only) using the turnin form. You should only turn in the classes and program files which you write/modify.
Don't turn in the GP142 files. Print out the receipt that appears, staple
it and your written report together, and hand it in during quiz section.