class Cave_System

Generally I like to write my classes from simplest to most complicated, but that's not always possible. In this case for instance, because all our other objects need to refer to the cave system we have to begin with its class definition.

Recall that in our first pass at the cave system object we said it consists of multiple rooms connected by multiple tunnels. This means that it will have to be a container type of some sort.

Looking at our pseudocode it looks like I was right about the container type, notice the square brackets in lines 6 and 9 which indicate a list:

 6         print('Choose from: ', cave_system.rooms[player.location].tunnels)
 ...
 9         new_room = cave_system.rooms[player.location] # Note simplifying alias.

Those show us that Cave_Systems have a rooms attribute that is a list. Based on its name, rooms is a list of the Room objects in the cave system. Now how to represent the pattern of connections between rooms? One simple way would be for each Room to know what other Rooms it is connected to, and that seems like a reasonable thing for a Room object to know so we'll make it an attribute of Room objects. Looking at line 6 above you can see that that's how it's written: the Rooms in the Cave_System's rooms attribute have an attribute tunnels that presumably lists the rooms the tunnels connect this room to.

So far so good, but I didn't do as well in my initial guess about the cave system's methods. My initial guess was that a cave system "should be able to tell us where you can go from here/what rooms are connected to this one; if a room has a bat; if a room has a pit; if the player is in a room." But, if you look at the pseudocode where these questions are actually asked you can see that they are asked of Room objects not of the cave system as a whole:

10         if new_room.has_bat():
               ...
12         elif new_room.has_pit():
               ...
15         elif new_room.has_wumpus():
               ...

This means that these methods properly belong to Room objects not Cave_Systems so we'll move them there.

What methods do cave systems have then? Almost none, but there is one slightly non-obvious one. Try spotting it...

Did you spot it in this line?

 2     print(cave_system)

There's no explicit method call there, i.e. no parentheses, but remember that for an object to be printable it has to provide an __str__ method so there is an implicit call to cave_system.__str__ in this line. Thus a Cave_System's only method (beyond __init__ ) will be __str__.

In sum this class doesn't have that much in it. It has to initialize a list of Room objects and provide an __str__ method. Here's its code,

Note that the constructor is passed a list of tunnel connections between rooms, and a map of the system. We can tell that tunnels is a list because of the way it is used with square brackets in the sixth line: tunnels[i]. We can tell system_map will need to be a string containing a printable map of the system because it is returned by __str__ and that method has to return a string. To make this more concrete here's the code to create a Cave_System object corresponding to our squashed dodecahedron cave system:

TUNNELS = [[1,7,19], [0,2,14], [1,3,6], [2,4,13], [3,5,11],
           [4,6,9], [2,5,7], [0,6,8], [7,9,18], [5,8,10],
           [9,11,17], [4,10,12], [11,13,16], [3,12,14], [1,13,15],
           [14,16,19], [12,15,17], [10,16,18], [8,17,19], [0,15,18]
          ]
MAP = '''
     19 - - - - - - - - - - - - - - - -  15
    /   \                               /  \ 
   /     \     - - - - 1 - - - -       /    \ 
  /       \   /        |         \    /      \ 
 /         \ /         |          \  /        \ 
 |          0          2           14          |
 |         /          / \           \          |
 |        /         /     \          \         |
 |       /        /         \         \        |
 |      7 - - - 6             3 - - - 13       |
 |       \       \           /        /        |
 |        \       \         /        /         |
18 - - - - 8       5 - - - 4        12 - - - - 16
  \         \     /          \     /          /
   \         \  /              \  /          /
    \         9 - - - 10 - - -  11          /
     \                 |                   /
      \                |                  /
       \               |                 /
         - - - - - -  17 - - - - - - - -
'''
cave_system = Cave_System(TUNNELS, MAP)

What does cave_system look like in memory? We can picture it like this:

.