Yet another 'Engine' post (ex43)

I have been working over ex43 and making my own game.
I have been stuck for a very long time trying to understand the Engine.
I have done many print() statements, used vs code debuger, pdb, even tried pudb(wouldn’t work).
light up google, Youtube and this forum. Over time the fog was lifting but was still murky. I went over Classes again then keep studying backwards. on Exercise 41: Learning to Speak Object-Oriented, something kinda clicked. so I walked through the engine and came up with this.

class Engine(object):

    def __init__(self, scene_map):
        #__init__ self and scene_map argument
        self.scene_map = scene_map

    def play(self):# method (1) play takes instance 
        # as first arugment(self)
        # self is all we need to get scene_map
        current_scene = self.scene_map.opening_scene()
        # set current_scene to an instance of scene_map
        # and get the opening_scene funtion (from Map())
        last_scene = self.scene_map.next_scene('death')
        # set last_scene to an instance of scene_map
        # and get next_scene funtion (from Map())
        # with the 'death' parameters

        while current_scene != last_scene:
            # current_scene and last_scene from play()
            # while current_scene does not equal last_last
            # (or while scene is not 'death')
            next_scene_name = current_scene.enter()
            # set next_scene to an instance of current_scene and call it
            # with the enter() funtion
            current_scene = self.scene_map.next_scene(next_scene_name)
            # set current_scene to scene_map, and call it with next_scene that
            # takes self and next_scene_name as paramiters

        # be sure to print out the last scene
        current_scene.enter()

If I’m on the right track, I’ll work on this and then Map() next until I can make my own.
Thank you.

Yes, this is very close. Take a look at this small correction to one of your comments:

        # self is all we need to get scene_map
        current_scene = self.scene_map.opening_scene()
        # set current_scene to an instance of scene_map
        # and get the opening_scene funtion (from Map())
        last_scene = self.scene_map.next_scene('death')

I think what happens is people (not just you) see this line of code and read it wrong because they read it as one cohesive piece separated by spaces:

self.scene_map.opening_scene()

This is actually more like 3 lines of Python in one:

scene_map = self.get('scene_map')
opening_scene_func = scene_map.get("opening_scene")
current_scene = opening_scene_func()

The . (dot) is acting as the get() function from dict and only getting that attribute from the object (self).

That means .opening_scene is not doing a special “Call a function”. It’s doing a get, and only a get. It’s exactly the same as self.scene_map, or myfriend.age. Then the () after opening_scene is what calls it, making it a function call.

Study that and then reply back to me what you think the comments for the next line should be.

Thank you sir, I will. melatonin is kicking in so I’m be on it all this week

I have been over this several times this week (I’ll save the sob story) and this weekend got, what I think is, an answer.

current_scene = self.scene_map.opening_scene()
# self gets 'scene_map' from the dict and sets it to scene_map.
# scene_map gets 'opening_scene' from Map()
# opening_scene() is set to current_scene

I know there is vocabulary I am missing. I have been reading a lot on dot notation, classes, modules and objects. I have tried all this week to type out comments. But as I think I understand and can explain I lose any capability to articulate an answer.

I came across something while reading up on this. I can’t recall it exactly, But something like python creates a dict of funtions or classes when it first runs. Is that what you are referring to or the scene{ } dict?

You can also try converting this into multiple lines of code. I’d do it like this:

current_scene = self.scene_map.opening_scene()

Becomes:

the_map = self.scene_map
the_opening_func = the_map.opening_scene  # <<--- NOTE no () to call it!
current_scene = the_opening_func() #<<< NOTE now I call it

Then take those lines and print out everything:

the_map = self.scene_map
print("the map", the_map)

the_opening_func = the_map.opening_scene  # <<--- NOTE no () to call it!
print("the opening function", the_opening_func)

current_scene = the_opening_func() #<<< NOTE now I call it
print("the current scene", current_scene)

Then, put it back together one line at a time:

the_opening_func = self.scene_map.opening_scene
current_scene = the_opening_func()

And the final step:

current_scene = self.scene_map.opening_scene()

Try doing this on every line of code that has more than 1 dot until you start to see how the chains of dots work.

A free service run by Zed A. Shaw for learncodethehardway.org.