Hello, loves! Tout le monde déteste l’IA.

Let’s take some steps toward stepping visually through dungeon creation.

I think the plan will be something like this:

  1. To step through a dungeon creation sequence, express it as a Composed Method or Composed Function, a method or function that calls other methods or functions.
  2. Produce a table of those methods or functions.
  3. Pass that table to the system in debug mode.
  4. Open the view.
  5. Every time the programmer types the step character, execute one more step in the table.

I’ll start by dividing up main into functions, I guess.

First attempt, I got it divided up OK but hadn’t thought about how to call it from the table. The table will want to consist of functions with all the same parameters, unless we did something Way Too Clever. If we make the parameters be the dungeon, we can get at the layout as needed. Better, though: let’s pass both dungeon and layout.

Ah, there is a key issue. When we start the view for the first time, we call arcade.run(). That method never returns until the game is over.

Therefore, any switching from step to step must be done in the key_press operation or similar interrupt.

That confused me for a while but should be no real concern, since that’s pretty much what we plan to do anyway. Carry on.

After a bit of effort, I’ve converted main to run from a table:

def main():
    # random.seed(35)
    # random.seed(234)
    layout = DungeonLayout(64, 56)
    dungeon = Dungeon(layout)
    screen_width = 16*dungeon.max_x
    screen_height = 16*dungeon.max_y
    arcade.Window(screen_width, screen_height, 'Caveat Emptor')
    dungeon.run()
    for m in make_build_table():
        m(dungeon, layout)
    view = DungeonViewMaker(dungeon).view
    view.run()
    # dungeon.add_passage(Cell(32,30), Cell(33,30))


def finish(dungeon, layout):
    layout.finish_map()


def make_build_table():
    return [
        make_diamond_in_round_room,
    make_a_diamond_room,
    make_a_round_room,
    make_random_rooms,
    finish,
    populate,
    add_content,
    ]


def populate(dungeon, layout):
    dungeon.populate()
    # target = random.choice(options)
    # DungeonViewMaker(dungeon).view.run()
    target = Cell(32, 28)
    dungeon.just_set_player_position(target)


def add_content(dungeon, layout):
    factory = ContentFactory()
    item = factory.receivable(name="a red key", resource='keyRed.png', scale=0.5)
    ...


def make_random_rooms(dungeon, layout):
    number_of_rooms = random.randint(8, 8)
    for _ in range(number_of_rooms):
        make_a_cave_room(dungeon, layout)
        make_experimental_room(dungeon, layout)

... # and so on on and so on and scooby-dooby-dooby

The game properly populates and runs. We’ll commit this. I think we’re ready for the next step.

Reflection

I spent some time trying to insert delays into the main, to see how things were progressing. I finally realized that that cannot work, because once we call arcade.run(), our main program never sees control again until the player quits. Aside from that and recognizing that I need the same parameters for each function in the table, which only took me a few moments to realize as I began extracting functions, it all went smoothly.

I remain pleasantly surprised that this seems to be going to be as easy as it has been. I was really expecting more trouble. It’s good to have a pleasant surprise once in a while, and I hope you have many.

See you next time!