Struggling to write object-oriented code; need help, advice

I’m still very much a beginner in the Python and programming world. But this isn’t my first week either. I’ve gone through many tutorials, several introductory books, and have even made a few scripts that are actually useful and I use them daily. I want to start creating more complex applications, not just little scripts that automate relatively simple tasks.

To that end, I’ve been reading about and trying to write object-oriented programs. I think I understand the concepts of OOP well enough to write a simple game. I know what classes and methods are, and I understand inheritance. I thought a good starting point would be to take programs I’ve already done and re-write them in an object-oriented style. But every time I try, I wind up getting stuck in some corner and can’t figure a way out.

For example, my latest attempt was to re-write a simple text adventure game I made a while following one of Al Sweigart’s tutorials. I thought I ought to start with creating the “world”, which I figured would be simple: I’ll create a “place” class to make several place objects representing all the different areas of the game the player can move to. Each place object will refer to the other place objects surrounding it, and that’s how I’ll get my player to know where he can move to. I thought this would work up until I started creating the Room objects and found myself in a trap. Here’s the game’s map for reference.

MAP = """

        +---------+    +---------+
        | Thief   O    | Bakery  |
        | Guild   |    |         |
+------++------O--+    +----O----+
| Used |
|Anvils|        Town Square     +--------+
|      O                        |Obs Deck|
+------++----O----+    +----O----/  /
        | Black-  O    | Wizard /  /
        | smith   |    | Tower    /
        +---------+    +---------+

"""

I started with the town_square object. To create this object, I need to pass in other Room objects, representing the exits the player can move to. But wait, I haven’t made an object for “north y street” yet, this will cause an error because I’m referring to an object that doesn’t exist yet. OK, no problem, I thought. I’ll just make a n_y_street room object before the town square one. But wait north is nothing, and I haven’t made a “nothing” room yet. So i make that class, and then I realize there is no way to do this without winding up with a NameError. And so I am stuck and I don’t know how I can make this game with an object-oriented program.

I understand the important terms, but I am struggling to actually implement anything object-oriented that is more complicated than a Dog class with a bark method. If anyone thinks they can help me over the hump, I’d appreciate it.

1 Like

In terms of OOP and separation of concerns. Room object might ask another Room object if it should know and care where exits from it leads. Probably not, so it might be good to have some yet another other object which’s role is to connect from one room to another - like a map or something.

Generally Python has a bit loose relation to the OOP. There are classes and all that stuff, but it’s not a requirement. There are languages that require to have everything in classes, but Python is not one of those. It’s perfectly fine to not put everything into classes, and have simple functions that are juggling with objects, either the built-in, or user made.

I’ve seen somewhere, to start thinking about making a class only when couple functions are using the same arguments and its starts to be troublesome to pass those around.

There’s great talk related to python and classes by Jack Diederich, with title that not always should be taken literally, but to keep it in mind: Stop Writing Classes - YouTube

1 Like

It’s hard to give a lot of advice witout (pseudo-)code or design patterns on how the code should function later on…

Like, you don’t make a “nothing” room, you just use placeholder-values. So if you want “Town Square” to be an object which contains the rooms as additional object - then it depends on how it would “hold” these.
Is it just holding coordinates, has it fixed positions where a number of objects can be, does it just have a data-structure holding values?

Also, how does the error occur? It sounds like your TownSquare is already referring to a room, before you create it. But why? What is it trying to do with the non-existent room?
I’d think you create the TownSquare, give it an empty data-structure to hold the rooms, then create the rooms and add them to that. Then when the player tries to do something, the TownSquare checks what rooms are within the data-structure and returns whatever necessary.
Obviously that’s just some quick thoughts. But it sounds like a logic problem, where the program is doing some actions that are not needed at that point in time.

I need to know how to type code that only allows people with certain permissions to use a certain command on a Discord Bot (like ban, kick, etc).

try opening your own topic instead of writing in other people’s topics

The game is supposed to work like a text-only version of Myst.

- while playing:
    - print text describing:
        - items in the room the player can interact with
        - 'exits', other places the player can go from here
    - player enters command:
        - `take <item>`: pick up an item, add to player's inventory
        - `look <item>`: get a more detailed description of an item in the room
        - `move <direction>`: move to an adjacent room.

Sounds so simple but I’ve been staring at a mostly blank file for days now. Not sure how to even begin going about this in an object-oriented way.

I mean, you need to make a plan on how to implement and use the object and how they interact with eachother.
Also scale it just WAY down and work yourself up from there.

Make a room, a locked door, a key, a player, an outside. That’s 5 objects.
Have the player start within the room and try to implement all objects and interactions such as the player can say “I am in a room with a locked door” and go outside to say “I am outside and the sun is shining” - representing that the player has indeed changed locations.

Once you got that, you can think about scaling it up to a townsquare with half a dozen rooms and four dozen objects scattered about.

I like your project @iSmashButtons , it sounds fun.

One tip I might give for dealing with OOP in Python is that objects are not static and they can change after they have been initialized. This is one way to avoid the “chicken or the egg” circumstance of objects refrencing other objects. As a simple example:

class Place():
    pass

town_square = Place()
thief_guild = Place()
bakery = Place()

town_square.adjoining_places = [thief_guild, bakery]
thief_guild.adjoining_places = [town_square]
bakery.adjoining_places = [town_square]

You can further refine working with these relationships by giving the Place class methods for dealing with them (such as getter and setter methods). This is useful as the relationships get more complicated.

town_square.set_adjoining_place({'north-west': thief_guild})
town_square.set_adjoining_place({'north-east': bakery})
print(town_square.get_adjoining_places())

# {'north-west': <thief_guild>, 'north-east': <bakery>}

In the same way, you can create a Player object that containers a reference to a Place object the player is currently located in. This should let you pull movement choices from that referenced object for the player to pick from, and avoid having to create “nothing” objects for places the player can’t move to anyway.

1 Like

Dont take things to extreme with OOC, it doesnt mean you shouldnt use functional practices, which generally suggest, if something doesnt exist, add it as a parameter and pass it when it does.
Your tale does remind me of when i was working on my sudoko solver and instead of making it fully functional, i created an object representing the sudoku and designed functions to work with that sudoku object, but then some functions were trying to work with values that were not even there yet ^^

Meanwhile in Python: “Let’s just turn EVERYTHING into an object” xD

Jokes aside, while OOP can be kinda pointless if you don’t intend to have more than one instance of an object at a time - in this scenario with several places and rooms, OOP seems liker a very good fit.