[Tutor] designing POOP

Alan Gauld alan.gauld at btinternet.com
Sat Feb 9 14:46:51 CET 2008


"bhaaluu" <bhaaluu at gmail.com> wrote

> the second chapter deals with a Blackjack game. One thing I noticed
> (and remember, this is a Noob's viewpoint): The classes seemed to be
> designed from small to large, rather than from large to small.

As I mentioned in an earlier mail it tends to oscillate in practice.
You start off looking at the problem to identify the basic classes.
Then you pick one or two and start designing those in detail and
that identifies lower level classes. When you reach the point of
being able to write some code you do so. The act of writing code
brings up issues that get reflected back up the design - maybe
even identifying new classes. Once you've written as much
code as you can you go back up to the problem level, using
your new found knowledge and design a bit more. Once you
know enough to start coding go back into code mode again.

This constant iteration between top level class discovery and low
level class construction is what Grady Booch refers to in his book
as "Round Trip Gestalt Design" and in practice is how most
software other than the very biggest projects is built.

> I've noticed in my tutorial that several small programs introduce 
> various
> classes as the chapter proceeds, then at the end, it is all used to 
> make
> the final program. That's fine for the book: no telling how long, or 
> what he
> had to do to get it to work that way.

One of the problems of tutorials (my own included) is that you
tend to focus on the code and never get round to explaining
to the student how you worked out which classes to build
in the first place! I tried to address that in the Games Framwork
case syudy in the paper book version (try your local library)
which deliberately sets out to create a class Framework step
by step. But its quite hard to explain design techniques at the
very early stages of programming. Thats why some of the
design books I mentioed earlier are good (especially Booch)
because they discuss the process of discovering classes and
objects in the first place, and provide some basic heuristics to
help.

> There is a castle which has several levels and each level has rooms 
> on it.
> The rooms have doors. The doors connect the rooms to each other. 
> Each
> room can have either nothing in it, a treasure, or a monster. Each 
> room
> has a description which describes 1) Is there a treasure in the 
> room? (and
> if so, what is the amount), 2) Is there a monster in it (and if so, 
> what is the
> Danger Level), 3) The room description, including where the doors 
> are,
> (N,S,E,W,U,D).
>
> I'd like to try and design this small part so that the Explorer can 
> move
> around the environment, from room to room, level to level. That's 
> it.
> The Explorer will be able to see, but not pick-up treasure (keeping 
> in
> mind that treasure can be picked-up in the final game). The Explorer
> will be warned about a monster in the room (keeping in mind that the
> monster can be fought in the final game).

Thats fine so you probably can start with a single room and your
Explorer. Get the explorer to ask the room whats in it and then
the Explorer can tell the Game what it has found.

>>> import room,explorer
>>> fred = Explorer('fred')
>>> room1 = Room(Dragon(),GoldRing(),Bread()
>>> room2 = Room(Serpent(),Bracelet(),Butter()
>>> fred.explore(room1)
>>> fred.describe()
I am in a room with a dragon, a gold ring and a loaf od bread"
>>> fred.explore(room2)
>>> fred.describe()
I am in a room with a serpent, a bracelet and a pack of butter"
>>>

Once you have that working its a short step to make the
castle contain a list of rooms with linkages between - possibly
using a variant of your procedural table, but with Room objects
rather than the raw data. The Room initialisation could read
a data file to get the contents of each room...
And the castle initialisation could read the data file to get
the layout of the rooms - sounds like a job for the Python
config file module maybe?

And hppefully from the codec above you can start to think
about what the expore method looks like inside? And maybe
what method the room might need to support that?

> Design in small chucks. The Castle needs to be setup. Can the Travel
> Table from the procedural game be used? Setup requires that the
> floorplan, or map of the castle be used to define each room on a 
> level,
> all the doors for the rooms, and treasure/terror. One array is used 
> in
> the procedural program. Whoops! Sorry. I'm not supposed to think
> about it like that!

No, thinking like that is fine when you are thinking about how
the methods inside the classes work. So long as the castle
stays concerned only with the layout of the rooms (how they
are connected to each other) and the rooms look after the
content within themselves. The Game class will then control the
movement and action of the explorer. So if the user wants the
explorer to go Siouth the Game can ask the Castle which room
(if any) is Sourth of the current Room - and the explorer knows
which room he is currently in so the Game can ask him that,
something like:

while True:
   direction = raw_input('What direction to move?[NSEW]").upper()
   if direction not in 'NSEW': break
   try:
      new_room = castle.whichroom(explorer.where(), direction)
      explorer.explore(new_room)
   except RoomError:
       print "Sorry you cannot move ", direction, "please try again"

> But in this game, all the doors do is connect the rooms. They don't
> have knobs or locks. They don't open or close. (Although they MAY
> have that ability in some future game?).

If they don;t do anything then leave them out for now. Remember
objects have behaviour. No behaviour suggests no object needed!

> possibly think of all the future things an object can do or be, but
> if the class is designed in a very abstract way, then it will be 
> easier
> to add a new behavior or characteristic in the future, if needed?

Thats the hope.
And often the additional behaviour is added by subclassing because
often you will have found a special category of your more abstract
class - a special type of room say, maybe a dungeon with
no easy way out... or one that reduces strength and wealth
more than usual...

And with that we again start to see how OOP allows us to extend
the game easily without breaking already working code.

> The castle has levels. Each level has rooms.

OK, Id start with a single level castle. Add up/down
between levels later only if needed. (A simple 3d mesh
might be all thats needed)

> in the castle. The equivalent of the castle in the card game would
> be the "deck of cards". But the deck of cards holds "hands" (rooms?)
> which are shuffled and dealt to people. It does something. What does
> the castle DO?

It determines the validity of movement between rooms.
Room 1 and Room 2 may be next door to each other but
the catle knows if they are connected (have a doorway?) or
whether you need to go via a corridor (another type of room?...)

See the example code above for one way to use the castle.

HTH,

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 




More information about the Tutor mailing list