5

I'm new to object-oriented programming, to java, and to programming in general, and as my first real project I'm trying to program the board game Monopoly.

What I've got so far is an array that can store objects of the class Square (which has various subclasses, like properties, the railroads, chance cards etc.). Player objects take turns in moving around on the board, calling a landedOn() method for whatever square they land on. Properties can be marked with an owner, and thus this owner will receive money if someone lands on his property.

Everything is going good so far, but there is one little thing that bugs me. I'm unsure about how to elegantly divide the houses in groups, or colors. There are a couple of groups of streets on the board, and you can only buy houses if you own all properties in the group. I can imagine how to program this, but the solution seems a bit dirty and "non-general" to me. How do I make a nice general solution?

To clear up: I want to be able to check whether all properties of one type are owned by the same player, in a general way, so that if the groups are changed, a property is added, or changes group, etc., I would not have to change a lot of code.

1
  • 1
    Also the rent on unimproved properties doubles when the owner has a monopoly. Commented Jun 10, 2013 at 22:21

2 Answers 2

4

The most elegant answer is probably an Enum.

Create an enum value for each color group, and when you create your Property object (which inherits from Square), pass the color group as a constructor parameter (since it is a required value to have a valid Property). Railroad, Utility and the like will not take this parameter, since they don't have groups, and they also inherit directly from Square (not Property).*

To check whether a player has all the properties in a given group, you could use a Lambda expression if you're using Java 8, or simply have a foreach loop along the lines of

for (property: allProperties)
{
   if (property.getGroup() == targetGroup && property.getOwner() != targetOwner) return false;
}
return true;

* It would also be valid to have a GroupedSquare class between Property and Square, with Railroad and Utility also inheriting from it and passing a hard-coded enum value, but I think that's less elegant.

5
  • Not for calculating rent when buildings are added, but the rent increases if a player owns all 4 railroads and the rent scheme for utilities changes if you own both of them, so they do get treated in a similar fashion as color blocks.
    – JeffO
    Commented Jun 10, 2013 at 23:03
  • @JeffO - I had had that thought, but since it would be the same logic to count how many RailRoad have a Owner set as it would to count how many GroupedSquare with a Group of Railroad have an Owner set, I went with the approach which divided that logic entirely. It could go either way, though.
    – Bobson
    Commented Jun 10, 2013 at 23:09
  • "..Property object .. inherits from Square". The squares on the board are not only properties - there's "chance", "GO", "Jail", for example. So then a Square might contain (composition/ has-a) a property, or Jail, or Chance; each with unique behavior. Just come up with an abstraction - very possibly an interface (vice abstract class) - so the Square handles everything the same way; calls "DoYourThing()" no matter what it is.
    – radarbob
    Commented Jun 11, 2013 at 16:02
  • @radarbob - Why would you use composition here? A Square **is ** a property, or a card-draw space, or Luxury Tax, or so on. The Square itself is abstract. Calling it a Space might be a better choice, but either works. Separating the actual things out and having them all inherit from an interface which gets stored on the Square is just adding needless complexity.
    – Bobson
    Commented Jun 11, 2013 at 17:18
  • I see the game board with its squares as being distinct and separate from what is done at that square. I can see how one would think of a property as a square because the game board is fixed - we can't move Reading RR. But in my mind's eye a property is not a square any more than I am a car when I drive home after work.
    – radarbob
    Commented Jun 11, 2013 at 18:00
2

An alternative to an enum by Bobson might be to have the groups as independent objects. By this you don't have to iterate over all atreets to see if a group omplte but can check the individual group only. In Pseudocode the impleemntation might look like this:

class Group {
    Set<Road> roads;

    bool hasAll(Player player) {
        for (road: roads) {
            if (road.getOwner() != player) {
                return false;
            }
        }
        return true;
  }
}

class Road {
    Player owner;
    Group group;

    bool canBuildHouses(Player player) {
        return group.hasAll(player);
    }
}

Over the enum approach this has the benefit that you can mov the group specific logic all in the Group class.

Now OO designes will still not like this due to the cyclic dependency (a Group has to know its member Roads and a Road has to know its Group) which can be solved by an event-based approach this would make this specific issue notably more complex but give way more flexibility for i.e. adding special rules as one could add extra rules like bonusses if a player contains a full side of the board or all roads starting with the same letter or something quite easily.

5
  • Which one would you have inherit from the Square? I assume Road, with Group being a separate class that just holds the collection of Roads?
    – Bobson
    Commented Jun 10, 2013 at 23:11
  • Massively more complicated than a simple three line function that will be plenty fast enough. Commented Jun 11, 2013 at 15:27
  • There is something to this Class Group idea. The rules and rent change as all like-properties get owned by the same player. This suggests that those rules can be encapsulated by a Group class. This concept does not negate Bobson's answer.
    – radarbob
    Commented Jun 11, 2013 at 16:04
  • a Road is the Square ...
    – johannes
    Commented Jun 11, 2013 at 16:34
  • @kevincline well, the question is which design works longtime when changing the rules a bit, or the board design or something.
    – johannes
    Commented Jun 11, 2013 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.