MCS 178: Introduction to Computer Science II (Spring 2011)

Project 8: Adventures in the Imaginary Land of Gack


Started: Wednesday 5/11; Due: Wednesday 5/18, by 10:00 p.m.

Overview

In this lab you will use object-oriented programming to extend an adventure game, the Land of Gack. This game is explained in section 5 of chapter 14 of Concrete Abstractions (starting on page 543) and we will spend a couple class days discussing the Java version you'll be working with. Your work in this project is very open-ended; you can choose for yourself how to extend the game. I strongly encourage you to talk over with us the choices you have made, not only with regard to new game features but also with regard to how they are programmed.

Differences in the Java version

Karl Knight did a complete re-write of the Land of Gack program from the original Scheme version, which we will provide for you as a starting point (see below). I am also providing the Javadoc-generated documentation. There are some differences from the Scheme version:

  • It has a GUI interface, using Java Swing
  • Clean-ups of capitalization, spelling, and punctuation
  • Elimination of the named-object class
  • Making the registry a class attribute within AutoPerson
  • Endowing each Witch and Wizard with its own favorite pond or chamber
  • Creation of a World class, which is the root of all worlds, such as GackWorld
  • Organization of the classes into three packages:
    • edu.gac.mcs178.gack, which contains the top-level classes, in particular Game.java, where you start the game.
    • edu.gac.mcs178.gack.domain, which contain the domain classes
    • edu.gac.mcs178.gack.ui, which contains the graphical user interface classes

Specific tasks

  1. Download Project8.zip and import it into your workspace. You can run the program by running the file Game.java. Do so. Then spend a little time exploring the project by reading the documentation.

  2. Once you have a copy of the game, you are to do exercises 14.33, 14.34, and 14.35. In coming up with ideas for the open-ended exercise 14.35, you may also want to look at exercise 14.42. All four of these exercises are reproduced below with minor editing to suit the current Java context. Be sure in the open-ended exercise to make changes which require all three of the following: some change or addition to the class hierarchy, some additional method, and some additional attribute (instance variable). This is a grading criterion for your project report.

  3. Exercise 14.33: First you'll need to familiarize yourself with the game. Run it as described above. Try to get from the dormitory to the computer lab without getting turned into a frog along the way. To make it more challenging, try to get to the lab possessing the scroll of enlightenment. If you want, you can make the other characters move several times after each move of yours (rather than just once) by using the "Pace" control. Be sure to get familiar with the game's other features too.

  4. Exercise 14.34: Modify the Land of Gack so that there is a new scroll, called "late lab report", in the dormitory. Now you can play the game with a new goal: Pick up the late lab report, go catch up with Max, wherever he may have wandered to, and try to give Max the report even though it's late. You'll need to add some additional mechanisms to the Person class and to the give procedure within GiveActionListener.java. Verify that at the end the lab report thinks Max is its owner, Max thinks the lab report is one of his possessions, and player no longer thinks the lab report is one of its possessions.

  5. Exercise 14.35: Of course, you can make the game much more interesting by adding additional twists. Implement some that interest you. We give a list of suggestions below but feel free to come up with some of your own. Be sure to describe in English whatever new ideas you introduce.

    • Add Chocolate as a kind of Thing with a method to beEaten. When a chocolate is eaten, the owner loses it and it is gone from the place where the owner is located. You can optionally add cute sound effects or make a wrapper or some crumbs appear at the place. Make some chocolates appear at food service.

    • Modify the Person class so people have an eat method that causes a chocolate they own to be eaten, much like the read method.

    • Now that we have chocolates, we can modify the Witch class to reflect a little-known property of witches: They can be bought off with chocolates. Change the act method so that if Barbara's victim has any chocolates, Barbara will take and eat one rather than turning the victim into a frog. Only victims who possess no chocolates will become frogs. This makes the game more interesting in that you have to decide whether to take the extra time to make a detour to food service for chocolates or go for speed but risk being caught unprepared by Barbara.

    • If you want to make the game harder yet, you can make it difficult to hoard protective chocolates by creating a troll who wanders around eating chocolates. Perhaps you should change Max from being a normal person to being the troll--it was probably just the fact that he wrote this section that kept him from being cast as a troll in the first place.

    • Introduce a general class, MagicScroll, into the game as a class that inherits from Scroll and that has a limited number of charges (let's say n) and when read the first n times invokes the doMagic method of self, i.e., of the particular magic scroll. However, there shouldn't be an actual defintion of doMagic in MagicScroll; instead the definition should only appear in more specific subclasses that inherit from MagicScroll. Define one or more specific kinds of magic scrolls as subclasses with interesting doMagic methods; for example, you might make a ScrollOfTeleportation class. These subclasses have the doMagic method but should not have a method for being read; that is inherited from the more general MagicScroll class. Only the specific subclasses will have instances created in GackWorld.java; there are no objects that are just MagicScrolls.

    • It makes the game rather easy if the title of a magic scroll tells what it does. You could add a feature so that initially the name of any magic scroll is just "a mysterious scroll", but when you read the scroll the first time the name changes to the actual title. This feature is particularly effective if you include scrolls with undesirable effects as well as desirable ones. Of course, you could counter by including a ScrollOfIdentification that can be used to decode the titles.

    • Currently Elvee, the wizard, always takes the first scroll at a place. Because some scrolls are more valuable than others, this action can make the game boring. Change the definition of the wizard class so wizards choose a scroll to take at random.

    • Feel free to add you own interesting kinds of people, places and things. While you are at it, you can also update any of the out-of-date game elements. Remember, though, changing some names or locations isn't as interesting as changing the overall patterns of behavior.

  6. Exercise 14.42: When a person says something in the Land of Gack, it is "heard" only by the player, in that whatever is said gets displayed. It would be more interesting if other objects within the Land of Gack itself could also hear--and potentially respond to--what was said. That way you could have characters who behaved differently if you said "please," magic portals that opened when you said "open sesame," etc. Note that this is just a suggestion; you don't need to do this.

    • Add a method in the Person class called hear that takes two arguments: the person speaking and what was said. The implementation in the Person class should do nothing because ordinary persons ignore what they hear.

    • Change the Person class's say method so that it invokes the hear method of each other person in the place where the person is speaking.

    • Now have fun introducing special classes of person that respond to what they hear.

    • In order for magic portals and the other magical objects to respond to spoken commands, they will need to hear as well. In Concrete Abstraction's version of the Land of Gack, this would be achieved by putting the hear method in a general named-object class, from which the person, place, and thing classes all inherit. However, in the Java version, this superclass was eliminated. Therefore, you have a choice of either independently adding hear to other classes, such as Thing, or reintroducing a NamedObject class after all.

What you must do

  1. Your programming will focus on Exercises 14.34 and 14.35 above. For 14.35, we will expect you to add at least two classes to the class hierarchy which should involve new methods and instance variables. You will also need to add appropriate user interface items (e.g., JButtons or JComboBoxes).

    When grading the programming part, we will look to see that the classes are well-designed, with methods in the appropriate classes. We will also check that the underlying objects are appropriately modified through the methods. For example, when one person gives a thing to another person, both persons, the thing, and the place they are in are appropriately updated. (Note: the state of the place will only change if the two people are in two different places, which you may or may not allow; if you do allow it, then the state of both places will change.)

    Also, part of your score on this part will be determined by the degree of difficulty of what you are trying to do. This is not to say that what you do should be overly complex. Just that if what you do things that are overly simple, we will not give full credit.

  2. You should describe in your own words what you were trying to accomplish in Exercise 14.35, and put this description in a readme.txt file, which you should put into a documents folder in Project8. This description need not be overly long; however, it will be helpful when grading the project.

  3. You should describe how you tested your new domain classes and the new methods that you added to the existing domain classes (such as the give method in Person). In general, there are two forms of testing: unit testing and integrated testing. The latter would involve running the game, and for this you should summarize how you did this, rather than including a transcript. For unit testing, I recommend that you put a main() method in the domain classes you created or modified (e.g., Person, because of the give method), and then create a few objects to test whether the desired behavior occurred. Descriptions of your testing (unit and integrated) should be in the readme.txt file.

  4. Finally, you should do a full class diagram for the domain classes, including both the domain classes I provided and the new ones you have added. (You should do the 7 classes in the package edu.gac.mcs178.gack.domain, not including TestDomain, which is just for testing). I recommend that you just write this by hand and hand in the hard-copy. To make more precise what you need to do, here is what would go in the instance variables box for AutoPerson:

        static registry : Registry
        threshold : int
        restlessness : int
    

    And here is what would go into the methods box for AutoPerson:

        getRegistry() : Registry
        setRegistry(registry)
        maybeAct()
        act()
    

    Note that I am allowing you to simply name the method parameters, rather than giving their types, and you only need to give return types for non-void methods. Also, only include new instance variables (i.e., not inherited ones) and new methods as well as those you overrode.

What you should hand in

Submit your Project8.zip file. You should be sure to include the readme.txt file mentioned above in the documents directory in Project8. You should also hand in the class hierarchy, which may be done by hand.

Gradesheet

We will use this gradesheet when grading your lab.

Submission

Use the procedure described in our instructions on submitting code document.