Good Morning All,
Today’s conversation with Dr. Baliga focused mostly on the O.O.D. Paradigm, the O.O. Design Process and my understanding(or lack thereof) of those concepts. The monopoly project provided a convenient context for that discussion, but largely we did not talk about monopoly per say. So it was certainly a worth-while meeting for me but you guys really didn’t miss anything.
Your criticisms today weren’t wholly deserved, as I’ll attempt to show below, but they weren’t off target either. I certainly didn’t mean to take away anything from you guys – I was just trying to get stuff done. So if you thought I was infringing on your learning space, I apologize.
About Design Documentation:
Did I jump to code to quickly? Yeah, probably. To me, once I came up with a overall design for Monopoly in my head – the easiest and most efficient way to document that design (for both myself and others) was to write it down in C++. Perhaps a more appropriate choice would have been a combination of pictures, English, and C++…
The offense was magnified because the only thing I gave you guys was code and a handful of under-verbose comments. This betrayed nothing of the hour I spent thinking about the design, the ½ dozen flow charts, or the pages of hastily scribbled yellow-pad scratch work I did before allowing myself near the computer. In reality I spent about 2 hours on the project, and only the last quarter was spent typing.
Note on Spoilers:
If you want to figure out the monopoly design for yourself and then compare it to my approach – now is a good time to stop reading.
The design is relatively simple. In fact a closer examination of my pseudo-headers will reveal I wrote down all the fairly obvious stuff, but avoided serious thinking like the plague. Take a look at the pictures. Monopoly_flow2.jpg shows my stylish desktop(KDE) running Koffice – Kivo to build the class hierarchy. Monopoly_flow3.jpg shows the hierarchy, but honestly my desktop is so much more interesting.
The Class diagram starts with a largely abstract Monopoly class which pulls everything together. Under it we have four sub-classes. The “Dice”class would actually be a fifth sub-class under Monopoly, a point I have conceded on, but forgot to add to the picture. “Player” and “Board” should be mostly self-explanatory for now. Space is where you would find Ogren’s virtual landedOn() function. “Card” would be the template used to instantiate individual ‘Chance’ or ‘Community-Chest’ cards…
Some changes if your comparing to the pseudo-headers: “ColorGroup” in the code has changed to “RealEstate”. Community-Chest and Chance spaces would be objects of class “Pot-Luck” for lack of a better generic name. Other would include ‘Jail’, ‘GO’, ‘Free-Parking’ ‘Go-To-Jail’ and ‘Luxury Tax’, though this might have to be further broken down into subclasses.
So lets imagine how the game might begin. Execution starts in main.cpp’s main() function. This calls the “Monopoly()” constructor. Amongst other things, this constructor creates a vector of players (owned by class Monopoly) and fills it by calling the “Player()” constructor as many times as needed.
Monopoly() would also call the “Board()” constructor which in turn creates a (fixed) array of <space> This is where all the spaces around the board would be defined. When Monopoly() was done creating the players, and the board, the game is effectively setup. Other tasks that might have to be handled here would be creating and randomizing the stacks of chance/community chest cards.
After Monopoly() returns a new function begins. PlayGame() would contain the programs main loop. As I envisioned it, the loop would primarily be calling players[playerID].turn(); over and over. In side turn() (a public function of class “Player”) all the events of a single turn would take place. Trading(or mortgaging/un-mortgaging) Property, buying/selling houses/hotels, then rolling the die and moving the player around the board. At that point Board::spacesArray[x].landedOn(); would be called.
This tripped me up at first. The function is virtual to class “Spaces” and the actual implementation of the function that is called, is in the leaf-classes below Space. So the entire concept of knowing or deciding “what kind of space it is” is entirely irrelevant. You don’t have to know. The right function just happens.
When this is done, landedOn() returns. When turn finishes whatever it has to do it returns. If the game is not over, playGame() finds the next player and calls the turn() function on them and the whole thing repeats; else playGame() returns and the game ends.
That’s pretty much it. The pseudo-headers go into the next level of detail on how I suggest accomplishing the most basic functions of the game. It flows straight from this design though – and that’s how it’s done.
Hope this clears up the confusion,