Hello, loves!

I have an on-line meeting that I can pay only small attention to. Herewith, a report on whatever tiny changes I find.

No plan This is just some time to spare, improving what I see. I’ll start from Dungeon, I think, but look to the views when Dungeon bores me.

Here is a method used only once other than by tests:

class Dungeon:
    # no longer in use?
    def set_player_position_with_interaction(self, cell):
        if self._interactions_allow_move(cell):
            self.just_set_player_position(cell)

It has something like seven tests, however. I think we’ll let it be.

There’s this method, which I used once and was proud of:

    def maker_flood(self):
        if len(self.flood_list) > 0:
            self.flood_list = SpriteList()
            return
        for cell, distance in (Flooder(layout=self.layout, origin=self.player_cell)
                .can_traverse()
                .flood()):
            cx, cy = cell.center_position(cell_size)
            text = arcade.create_text_sprite(text=str(distance),font_size=8)
            text.center_x = cx
            text.center_y = cy
            self.flood_list.append(text)

It fills the screen with numbers reflecting the distance of the cell from the current player position. It’s not useful just now but if w get into searching trouble, it may come in handy. We’ll preserve it.

This is awkward:

class Dungeon:
    def contents_at(self, cell):
        return self.contents[cell]

Dungeon maintains self.contents as a dict[Cell, list[Content]]. From a code-reading viewpoint, one would prefer cell.contents() or cell.contents. Cells, however, do not know the Dungeon, only the Layout. This may be hinting that contents should be a layout property. I think that would be a bit of an invasive change. But maybe not, if we “just” forwarded.

Let’s see how DungeonLayout would feel about that.

class DungeonLayout:
    def __init__(self, max_x=10, max_y=10):
        self.max_x = max_x
        self.max_y = max_y
        self.cells: dict[tuple[int, int], Cell] = dict()
        self._create_cells(max_x, max_y)
        self.rooms = []
        self.border_map:BorderMap|None = None
        self.passages: dict[tuple[Cell, Cell], bool] = dict()
        self.room_map: dict[Cell, Room] = dict()

Let’s change Dungeon here:

    def contents_at(self, cell):
        return self.layout.contents_at(cell)

    def place_content_at(self, cell, content):
        self.layout.place_content_at(cell, content)

    def run(self):
        self.layout.run_contents(self)

    def remove_content_from_cell(self, content, containing_cell):
        self.layout.remove_content_at(containing_cell, content)

That breaks 12 tests, no surprise there. In DungeonLayout

class DungeonLayout:
# contents

    def contents_at(self, cell):
        return self.contents[cell]

    def place_content_at(self, cell, content):
        self.contents[cell].append(content)

    def find_cell_containing_name(self, item_name):
        cell = None
        for candidate, items in self.contents.items():
            for item in items:
                if item.name == item_name:
                    cell = candidate
        return cell

We are green and the contents dictionary is gone from Dungeon. I find two more methods and they have no tests:

    def remove_content_from_cell(self, content, cell):
        self.contents[cell].remove(content)
        
    def run_contents(self, pub_sub):
        for cell, contents in self.contents.items():
            for content in contents:
                content.run(pub_sub)

That should be corrected. And we can do some convenience methods in Cell now. Possibly get rid of some of the forwarding.

This is enough for an afternoon’s idleness. Commit: moving contents handling to Layout. Forwarding in Dungeon is in for now.

Summary

Small steps, small improvements. Done over time, done all in a batch, doesn’t matter. Things improve. This is the way.

Postscript

Adding contents() as a method on Cell lets me remove Dungeon.contents_at entirely. I think a global replace or two might do the same for the remove method. We’ll leave that for another day.

See you soon!