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.
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 Player s 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. |
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.
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); }
Here are some ways you can work smart.
Square
, along with a constructor.Monopoly
class contains a main
method with a
number of tests. These tests help verify that the Monopoly
,
Player
, and Square
classes are working as they
should. Make sure this main
method runs. Most of the tests will
fail. Start with the first test. Get it to pass by adding a property or two.
Don't move on until it passes. Then implement the code necessary for the second
test to pass. Continue on until all of these tests pass.Monopoly.main
. Write the code required for
them to pass.monopoly.Main
. Descriptions of all
the properties, names and balances of the players should show.Monopoly.playGame
. Identify where the state of
Player
and Square
objects change. Call
updateAllViews
at each of these places. Verify that changes are made
in the user interface.main
method in the class you're working on to do the testing. This is called
unit testing and is an important part of delivering quality
code and maintaining harmony with your teammates!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.
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.