This is the first, of a series of three articles. This first covers an historic, non-technical look at my own learning experiences with C, C++ and OO design and discusses the development stages of a 'pet project' of mine. The second article looks at the first OO attempt at this pet project and the final article looks at using UML and Patterns.
A Learning Experience
How people learn is in itself a fascinating topic but in software engineering one thing is for sure - whatever theories are out there - it's the 'doing' that reinforces what is taught in schools and universities or read in books.
I've been working in the computing industry now for nearly twenty years and, despite it being full-time employment, I still dabble at home on various 'pet projects'. Since early pre 'A'-level days there has been one project in particular that has been used to help me understand many aspects of design and implementation.
That project is 'to write a Monopoly® program'. It's a small, or at least well-contained, project with a clear goal, but nevertheless presents enough problems that continually manifest themselves in 'real-world' projects. Tackling the problems on this 'pet project' has helped me understand design issues and decisions that have been made on projects throughout my working life. More importantly perhaps, it helps to understand what the consequences of those decisions will be.
Following is a description of each of the stages that project has been through together with my successes and failures. It is assumed that the reader knows the basis of the game. If not you'll find them document on the web.
The Stages of this Development
The Monopoly program has gone through a number of different stages, for different reasons and different motivations. To date these are: Assembler; C; "Windowed" C; Microsoft Windows; Object-Oriented; C++; Visual C++; and finally Now!
Each stage is described briefly giving a little of the background and environment, finally stating if that stage was 'a success', 'a failure' or both.
Stage 1: Assembler
Wet behind the ears, and still at school. Thanks to the DECSystem-10 at Hatfield Polytechnic. We were being taught Dartmouth BASIC, but MACRO-10 (the assembler language) looked much more exciting. It allowed access to the nuts-and-bolts of the system (and controlled the lights on the front-panel of the CPU - wow!). I just had to learn MACRO-10. Together with a school chum we decided to tackle a program to play Monopoly and since then, as you can see, the theme has stuck.
Success 1) The program was finished and it worked (sort of). It controlled the game, allowed sites, houses, etc to be bought, sold, and exchanged.
Success 2) Although we hadn't been taught formal structured design and programming techniques, we ended up with a number of small routines performing well-defined tasks. We couldn't have known it at the time but since then I've seen many worse structured programs written by professionals whose experience should have taught them better.
Failure 1) One known unfixed bug - a flag was used for the "Get out of Jail free" card, indicating if the card had already been picked and kept by a player. The card (not being an "object") physically remained in the array of chance / community chest cards to which it belonged. On the occasions the next chance / community chest card to be picked was an "already owned" "Get out of Jail free" card it politely printed:
You have picked: You have picked: "next card in the array"
onto the ASR-33 Teletype (yep VDUs weren't around then - dates me huh?).
Failure 2) For the computer's turn, when it landed on a site that would complete a set, it would sell hotels and houses, mortgage other sites up-to-the-hilt (including those in the required site's colour-group) in order to purchase the final site. Not a very good strategy.
Failure 3) It was fixed to only allow one player and the computer to play the game.
Now out in the real world - but still green. At that time programming in FORTRAN-IV and a bit in 'C', but because the usual commercial deadlines, if a program worked one wasn't allowed to go back and clean-up the design or the code.
Learning 'C' via 'on-the-job training' is all very well but only a limited 'Fortran like' subset of the language got used. I wanted to really understand structures, macros and other bits of the C language that just weren't there in FORTRAN. I bought a copy of Borland's TURBO-C, and succeeded in learning a lot more C.
Failure 1) The Monopoly implementation (which would have been simple console I/O) never really got off the ground. I started to read the Borland manuals about graphical interfaces and other exciting stuff that would make the whole interface to the game much more user-friendly. It changed my ideas about the user interface and a redesign was beckoning.
Stage 3: Windowed C
The objective this time was simply to have a much jazzier interface, coloured boxes on the screen with coloured text in them - not Windows as we know it today.
Borland C was still the mainstay of the development but Borland Prolog also got purchased, which I was sure would be useful for the decision making of the computerised players.
Success 1) Prolog was fun. I succeeded in writing a program to solve the peg board game "Solitaire". I also started writing a few useful graphical library routines, painted a few "Title Deed" and "Chance / Community Chest" cards on the screen.
Failure 1) Well - Solitaire isn't exactly Monopoly is it? But then along came...
Stage 4: Microsoft Windows
Yep - here it was in all its glory... Windows/286! The wonderful, colourful text-filled boxes now started looking somewhat boring... and here was this mouse thing that could be used for an even jazzier user-interface.
The objective here then was still to concentrate on improving the user-interface. The trouble was the version of Borland C wouldn't allow Windows programs to be built, because of a special 'prologue' piece of code inserted by the compiler at the start of each routine.
So after wading through a few tonnes of documentation for the newly purchased Microsoft C compiler and Software Development Kit, my first Windows programs were being written.
Success 1) Obtained firm basis for the way Windows works "behind the scenes". Such things are hidden to today's developers by more and more layers of programmatic interfaces.
Failure 1) As far as good old Monopoly was concerned... complete failure! Windows required so many new ideas simply to experiment with and understand there was no time for development. Dealing with mouse movement, creating windows, updating menu etc all required little experimental programs. But the hankering was still there. I still wanted my Windows Monopoly program! (Persistent eh?)
Stage 5: Object-Oriented
Along came two things at once. Windows 3.0 (a vast improvement on /286) and an object-oriented Windows development environment / language called Actor!. I didn't really buy Actor! to learn OO techniques, but because it promised quicker development of Windows programs and it also ran under Windows V3.0.
Success 1) A good grounding for OO programming - understanding "objects", inheritance and polymorphism.
Success 2) Also the promise of faster development was delivered because a completed version of the Monopoly program (without "computerised players" though) was created.
Success 3) Learnt even more about Windows and had my first taste of the benefits OO programming and some simple OO design techniques.
Failure 1) Still hadn't completed the goal of having a Monopoly program with computerised players.
Failure 2) A few things fairly essential to Monopoly (like bartering of assets!) were lacking, but I was still pleased with the result.
Stage 6: C++
At this point the reasons behind the development of the pet project became somewhat more commercially biased. I thought C++ was going to be a more beneficial for my future career than Actor! I was also interested to see how the OO programming techniques I'd learned in Actor! were applied in C++.
This was back to Borland and their Turbo C++ version. The integrated development environment was much better than Microsoft's offering at the time.
Success 1) Another completed a version of the Monopoly program.
Success 2) The user interface was even better. Little pop-up windows containing "For Sale" or "Sold" signs were springing up across the screen.
Success 3) The complete rules of the game were programmed - assets could be bartered, various "House rules" that I've come across from other people were allowed as program options.
Success 4) Understanding the C++ syntax and its view of OO programming.
Failure 1) Still hadn't completed the goal of having a Monopoly program with computerised players, but I was still really pleased with the result!
Stage 7: Visual C++
My reasons for going back to Microsoft are again, rightly or wrongly, commercial. I suspected that (for PC based developments at least) Visual C++ experience would be more advantageous than that under Borland's IDE (sorry Borland).
So here I was re-learning the Windows interface through the use of the Microsoft Foundation Classes.
Success 1) Commercially it paid off. I was able to use the experience of Visual C++ to get on to a project at work that otherwise I would never have been able to start.
Failure 1) Didn't complete the "Microsoft-compatible user interface" version of Monopoly.
Stage 8: Where I am now!
Stages 6 and 7 were definitely biased toward my career, but now I'm back to my personal learning goals, even though they should help my career as well.
It's all very well being able to write C++ programs and use many of the features of the language, but it's just as important to design classes that work together well, that are maintainable and extensible. Although I believe my OO design to be good (don't we all?), I still want to improve it further.
A review of the book "Design Patterns" [ GoF ] interested me, and it was bought purely on the basis of the review / reviewer and, for anyone interested in design, I can certainly recommend it.
I've been analysing the "Patterns" in the above book and asking myself how they, if they or where they apply to the Monopoly program.
Also (having 'completed' two programs) I have decided to start 'designing' the program from scratch so, in parallel with looking at Patterns, I've been using UML with the demo version of Rational Rose V4.0 that comes with "UML Toolkit" [ Eriksson- ]
In part two I'll take a look at some of the classes in the completed implementations and their dependencies on each other and discuss what's wrong (or right) with them, also I'll take a look at how the program performed certain tasks.
In part three I'll take a first stab at applying some Patterns to the program design.
John Merrells comments: I was a student at Hatfield when the Dec-10 was melted down for precious metals. The night before its final demise some of my fellow system junkie friends logged an extensive session with the machine. Recording a final conversation with this venerable beast as an epigraph of is service. With this huge text file they spent many hours constructing a perfect emulation of the fated machine. Before departing to their prefabricated halls of residence, they left a few terminals logged into the fake Dec-10. For days the ghost of the Dec-10 would crop up in various corners of the computer center, haunting the engineering population of Hatfield Poly.
Unfortunately the system administrator (otherwise known as the Angel of Death) decided that this emulation was in fact an evil trojan horse designed to harvest user passwords - sigh - so they hunted down the ghost of the Dec-10 and killed that too. (BOFH, for those of you who recall the early days of usenet humor.)
[GoF] Design Patterns - Elements of reusable software Gamma et al; Addison Wesley; ISBN 0-201-63361-2
[Eriksson-] UML Toolkit Eriksson and Penker; Wiley; ISBN 0-471-19161-2