Provided Code

Download the provided code, monopoly.zip to help get you started. The project contains two packages. monopoly.gui contains a graphical user interface (view) while monopoly.model will contain the model. Your early work will be exclusively in the model.

About monopoly.gui

The code in monopoly.gui is complete and working. You should not modify it in any way until after your program plays a legal game as described by the rules outlined in the Requirements. Furthermore, most of the classes and methods have package visibility rather than public visibility. You are not permitted to change this.

The user interface, monopoly.gui, requires that the model contain the following public classes with the given public methods:

Class/Method Description
Square A class representing a property such as “Vermont Ave.” or “Reading Railroad” or the special property “Go”.
getDescription Returns a string describing the square. The string should contain newline characters ("\n") to format it into appropriate lines.
getPlayers Returns an array containing the Players currently on this square.
addView A method to add another view to be notified whenever this part of the model changes.
Player A class representing a player in the game.
getOwnedPropertyNames Returns a filled array of the names of the properties owned by this player.
getName Returns a string which is the name of the player.
getID Returns an int which is the ID number of the player.
getBalance Returns an integer representing the player's current bank balance.
getNetWorth Returns an integer representing the player's current net worth.
canBuyOccupiedSquare Returns true if the player can buy the property they have landed on; false otherwise.
buyHouse Instructs the player to purchase a house for a property.
buyOccupiedSquare Instructs the player to purchase the property they just landed on.
addView A method to add another view to be notified whenever this part of the model changes.
Monopoly A class representing the entire game.
playGame A method that plays the game. When this method finishes, the game is over.
getNumSquares Returns the number of squares on the board.
getNumPlayers Returns the number of players in the game.
getSquare Returns the property object specified by a parameter.
getPlayer Returns the player object specified by a parameter.

About monopoly.model

The model is where you will spend the vast majority of your time in the first part of the project. The provided code includes the classes required by the interface and stubs for the methods the user interface calls. A stub is just enough for the program to compile — if the method is a command, it will be empty; if it's a query, it will return a constant such as false or 0. It will be your job to implement these methods as specified above. Below is the class diagram showing the classes and methods required by the user interface.

You will also need to add several more classes and methods to the existing classes to make your Monopoly game work as specified.

Communication Between the Model and the User Interface

Every time the model changes, the view (the display portion of the user interface) must update the information it displays. The view is notified of changes in the model when the model calls the view's updateView method. The view then queries the model for its current state and redisplays itself. That is, it uses queries such as getBalance and getOwnedPropertyNames to find out what information it should display to the user.

The model is not one big thing — it contains many distinct parts. There are a relatively small number of Player objects and a larger number of Square objects. Similarly, the user interface is not a single, massive, view. Parts of it are dedicated to displaying players while other parts are dedicated to displaying properties. Each part of the model (each Player object and each Square object) keeps a list of views that are concerned about changes to that Player or Square object. Each view has a method named updateView. When a model object changes, it should call the updateView method for each of the views on its list. A view is added to the list by calling the addView method in Player or Square.

The provided code includes a method, updateAllViews in both the Player and Square classes. You will need to implement this method so that it calls the updateView method for each of its registered views. You will call this method whenever the model changes. For example, a method to change the bank balance might be:

public void adjustBalance(int amt)
{  this.bankBalance += amt;
   this.updateViews(this);
}

Advice

Here are some ways you can work smart.

Getting Started

Hints

Resources

Dealing with Randomness

A game such as Monopoly inherently relies on the randomness of throwing a pair of dice. In a program, this is simulated with a random number generator such as Math.random(). However, debugging a program that uses a random number generator is difficult. Efficient debugging relies on being able to reproduce errors at will — something that a random number generator will not do!

One solution is to use polymorphism. The provided code includes a superclass named Dice which has a single method, getRoll. It also provides two classes which inherit from this class. The first, RandomDice, should use a random number generator to simulate rolling two 6-sided dice. The second, pops up a dialog box, asking the user (debugger!) for the value to use for the “roll” of the dice. Use RandomDice to play the game; use UserInputDice for your debugging. Every time you run the program, you will have the option of debugging (using UserInputDice) or running a normal game (using RandomDice). The console window will prompt you for your choice. You will need to finish implementing the determineDiceType method in the Player class for this to work (as well as finish implementing the RandomDice class).

Note: Sometimes the dialog box for the UserInputDice appears behind the Monopoly game window. So, if you can't seem to find it on your screen, use Alt-Tab to select your game and the dialog box shoud jump to the front.

Initialization

There are many times when you want to start mid-way through a game. Perhaps a user wants to play a previously saved game. Or you're debugging the code that handles a bankrupt player or the code that handles the end of the game. In each of these situations, it's handy to be able to read the state of a game from a file. Furthermore, our testing procedures will expect your program to load a known game such as those contained in testGame1.txt or testGame2.txt. Your game must work with all possible input files of the format outlined in these examples. Use these two examples as a starting point and feel free to make your own.