Skip to main content.

Assignment 3: Inheritance, Abstract Classes, and Final

Objectives:

Due: Wednesday, Oct 16 before class

Recommendation: Complete at least through part 2 before Monday, for timely completion of the assignment and to identify any issues/questions/comments you may have.

Set Up

Cloning the Repository

In your terminal, go to the directory where you are keeping your repositories for CSCI209. Clone the repository for this assignment.

Add your name to the README file -- you're going to be answering questions in this file for this assignment.

Part 0: Background and Preparing for Assignment

Compiling and Running the Code

  1. Compile the code using javac *.java or javac Game.java.
  2. By compiling Game.java, the other classes that it uses are also compiled.
  3. Run the game by executing java Game
    You should see a black pop-up window with a little dude--the professor--in the bottom right corner of the screen, walking.
  4. Using the arrow keys, move the professor around the screen. Use the space bar to stop him.
  5. To stop the program, close the window.
  6. To see what I'm hoping to see when you're done (if you also do the extra credit), go into the demoClasses directory and run
    java -cp Game.jar Game
    Your Goblin's movement may not be as aggressive as mine, but it also shouldn't be too pokey (and probably not much more aggressive--give players a chance to win).

Understanding the Code

The "game" of CSCI 209 has changed! We're leveling up! From this assignment on, you'll start spending much more time thinking about and understanding code and its design more than writing new lines of code. It's tempting to rush through this important step, but spending time understanding code (and then understanding the problems) will pay off in that you should have an easier time writing code.

To help you with understanding the Game code, read the Javadocs for the game code. Refer back to them while completing the assignment, as it may help you to figure out what is inherited and what each object can do.

I tested indentation of the given code in two text editors, but when looking at students' text editors that I don't have, I'm seeing indentation issues. Please fix the indentation as appropriate. (This won't be an issue soon; we just have some more learning to do before that.)

  1. Start by looking at Game.java. There is a lot of code related to the animation that you don't need to worry about understanding. Focus on the main and play methods as well as the instance and static variables.

    The main method creates a new Game object, including setting up the window. main also calls the play method, which starts the game running.

    The play method creates the professor and takes the professor's turn (which moves the professor). The professor's direction is determined by pressing keys (see the keyPressed method).

    Consider why some variables are (appropriately) static and some are instance.

  2. Then, look at GamePiece.java. (This class contains some less-than-ideal coding practices. Bear with me--you'll fix them soon!)

    Note the instance variables, the constructor, and the available methods--especially the takeTurn(Game game) method.

  3. Now, look at Human.java. Look at the class's constructor and the takeTurn method. Hopefully, you're now seeing how the pieces fit together.

Part 1: Creating Child Classes (60 pts)

There should be a lot more thinking than there is coding for this part. The amount of code you need to write is not huge. Think about the behavior of each class and how that should be implemented.

~~~ FAQ ~~~ Don't look at this until after you've attempted to solve this part.

  1. Create a Goblin class that inherits from GamePiece. There are several animated gifs to choose from. A Goblin should "chase" the professor instead of just standing there, which is what the inherited GamePiece's takeTurn method does (because the piece's coordinates don't change). Since you are overriding the takeTurn method, the method should have the same signature (e.g., the same parameters) as the parent's takeTurn method. How can you make the compiler help enforce that the child class's method has the same signature as the parent?

    Some illustrations to help frame your thinking.

    The implementation of Goblin's takeTurn method should look completely different from the Human's takeTurn method. They do not move in the same ways (i.e., the Human moves based on keys pressed; the Goblin chases the Human). Consider this hypothetical: if the Goblin was so much like Human, why wouldn't the instructions be to make the Goblin a child of Human? So, their implementations are probably pretty different.

    If you are tempted to change the method signature or write code that violates encapsulation, stop and consider what objects are available to you and if they have any methods that could be useful. Look at the code and/or the Javadocs.

    After trying to implement the Goblin class, you can jump to Part 2 to test if it's working, but just adding in the Goblin (not the Treasure). Then, return to here for instructions on how to implement the Treasure class.

  2. Create a Treasure class, another child of GamePiece, whose image is the gem. The gem will move around the window, periodically and randomly. Note that the Treasure should not change positions every time takeTurn is called within play. In other words, sometimes, when Treasure's takeTurn method is called, the treasure doesn't move. (It is taking a turn; it just doesn't move.) Also, note that the top 20 pixels of the window (indicated by YMIN_DISPLAY) are covered by the menu bar.
  3. Clean up your classes. Is there irrelevant code?

Part 2: Updating the Game Class (15 pts)

  1. Update the title bar for the game so that it has your name in it.
  2. Update the Game class to have instance variables for the Goblin and Treasure objects.
  3. Edit Game's play method. Create a Goblin object and a Treasure object. Start the Goblin in the upper left corner. The Treasure should start in the center of the window.
  4. Call the Treasure and Goblin's takeTurn methods.
  5. Call the Treasure and Goblin's draw methods to display them.

Part 3: Using an Abstract Class in the Game Application (35)

Refactoring

This assignment is an example of a typical design/implementation process. Start with the original code design: inheritance from GamePiece class. You realize it could be designed better, so you change the design/implementation. With the revision, it is now easier to add new functionality to Game. This is called refactoring. You are not adding functionality, but you are changing the code to improve its design/readability/maintainability in some way.

Now for the refactoring of your code:

The coding for this part of the assignment should be straightforward. The explanations to the questions below are more important.

Documenting Design Decisions

You are going to document your design decisions in the README.md file, under "Design Decisions".

Extra Credit (up to 15 points)

Complete all of the above requirements before doing extra credit. A good implementation of above, using best design practices, is much preferred to completing the extra credit.

Add the overlap method to the GamePiece class. The signature for overlap will look something like
public boolean overlaps( GamePiece gp ). It will return true iff the GamePiece overlaps the GamePiece passed to the overlap method as a parameter. Note that, if you haven't done so already, you'll need to adjust the value of the img_width or char_width variables of the respective child classes, depending on the size of animated gif you chose. Try a value of 15 to start.

There is a lot more that can be done on this assignment--actually making the game stop, implementing winning or losing, adding goblins (with different types of movements), ... Be creative, but keep the code neat.

Submission

As usual, put all of your code in your GitHub repository that you and I can access.

Grading (115 pts)

You will be evaluated based on the following criteria: