tags:

views:

161

answers:

2

I'm thinking of writing a CLI Monopoly game in Ruby. This would be the first large project I've done in Ruby. Most of my experience in programming has been with functional programming languages like Clojure and Haskell and such. I understand Object Orientation pretty well, but I have no experience with designing object oriented programs.

Now, here's the deal.

In Monopoly, there are lots of spaces spread around the board. Most spaces are properties, and others do other things.

Would it be smart to have a class for each of the spaces? I was thinking of having a Space class that all other spaces inherit from, and having a Property class that inherits from Space, and then having a class for every property that inherits from Property. This would mean a lot of classes, which leads me to believe that this is an awful way to do what I'm trying to do.

What I also intended to do, was use the 'inherited' hook method to keep track of all the properties, so that I could search them and remove them from the unbought list when needed.

This sort of problem seems to arise in a lot of programs, so my question is: Is there a better way to do this, and am I missing something very crucial to Object Oriented design?

I'm sorry if this is a stupid question, I'm just clueless when it comes to OOPD.

Thanks.

+6  A: 

You're on the right track, but you've gone too far, which is a common beginner's mistake with OOP. Every property should not be a separate class; they should all be instances of the Property class. I'd do classes with attributes along these lines:

Space

  • Name
  • Which pieces are on it
  • Which space is next (and maybe previous?)
  • Any special actions which take place when landing on it

Property (extends Space)

  • Who owns it
  • How many houses/hotels are on it
  • Property value
  • Property monopoly group
  • Rent rates
  • Whether it is mortgaged

So, for example, Boardwalk would be an object of type Property, with specific values that apply to it, such as belonging to the dark blue monopoly group.

Pesto
Oh, I see. That does sound better. I'm still trying to figure out how I would keep track of all of the properties. Wouldn't instantiating Property **that** many times be considered boilerplate though? I'm sure there is a better way to instantiate Property for every property without explicitly instantiating it for every single property. I'm just not thinking of it. :p
Rayne
Classes *are* boilerplate. They are intended to wrap up the repeated properties and behaviors. As to explicitly instantiating it for every single property, you'll have to instantiate the properties no matter how you do it. But you don't *have* to do it explicitly. You could wrap up the data about the properties in a, for example, XML file and have the program instantiate each one at startup.
Pesto
I see. It would be trivial to just instantiate them all one after the other, to do what I want to do with them. I wasn't sure whether or not instantiating them so many times in a row would be considered a bad thing to do. I appreciate your responses. You've helped me a lot. :)
Rayne
+1  A: 

Classes for spaces is probably not a bad idea; but let's see why that's the case.

If you were writing this in a procedural language, where would the majority of the 'if' and 'switch' statements be? They'd be in determining what happened to each player when they landed on a space. In OO, we want to prevent as many if/switch statements as possible, and replace them with polymorphism. So, clearly, if we create many derivatives of Space, we will prevent a large number of if/switch statements.

But before we make that leap, let's look at the metaphor of the game. The game is all about a city. Addresses, streets, utilities, public works, jails, etc. Each square on the board represents some kind of location in the city. Indeed the players travel through the city paying rent (or some other action) anywhere they happen to land.

So let's call the spaces, CityBlocks. Each CityBlock has an address, like "Boardwalk" or "Electric Company", or "Community Chest". Are there different types of CityBlock objects? Or should we simply consider CityBlocks to be locations that have a certain kind of ZoningOrdinance?

I kind of like that. |CityBlock|---->|ZoningOrdinance|

Now we could have several different derivatives of ZoningOrdinance. This is the "Strategy" Pattern. I rather like the flexibility this give us, and the separation of 'where' and 'what' that it provides.

You'll also need a Game class that understand the rules of dice, tokens, FreeParking, Passing Go, etc. That class will manipulate the players, and invoke the methods on CityBlock. CityBlock will invoke methods on ZoningOrdinance.

Anyway, that's one way...

Uncle Bob