I think ensure_connected can fail. Let’s prove it, then fix it.

I need an afternoon distraction, so we’ll try some more code improvement. We’ll start with the path-making code we find lying about.

class DungeonLayout:
    def ensure_connected(self):
        if self.is_fully_connected:
            return
        room = self._straight_path_room()
        self.add_room(room)

    def _straight_path_room(self):
        cells = self._straight_path_cells()
        if cells:
            return Room(cells, 'path')
        else:
            return None

    def _straight_path_cells(self):
        cells = []
        suites = self.define_suites()
        for s1, s2 in zip(suites, suites[1:]):
            cells.extend(s1.find_path_cells(s2))
        return list(set(cells))

This code gets a list of all current suites—each suite being a collection of rooms that are directly adjacent—and then creates a path between each pair or suites 0->1, 1->2, and so on, collecting all the cells of all those paths into one room, which it adds to the layout.

I suspect that this code can fail to connect the dungeon as it stands, if the rooms are arranged poorly enough. Let’s try to write a test for that.

    def test_connected(self):
        layout = DungeonLayout()
        Cell.create_space(5, 5)
        r_0 = Room([Cell.at(2,0), Cell.at(2, 1), Cell.at(2,2),
               Cell.at(3,2), Cell.at(4,2)])
        layout.add_room(r_0)
        layout.add_room(Room([Cell.at(4,4)]))
        layout.add_room(Room([Cell.at(4, 0)]))
        assert not layout.is_fully_connected
        layout.ensure_connected()
        assert layout.is_fully_connected

The map looks like this, if I’m not mistaken:

..0.2
..0..
..000
.....
1....

So our current code will connect 0->1 but then be unable to connect 1->2, leaving two suites, (0,1) and (2).

I expect the test to fail, after three or four attempts to transcribe my picture to coordinates by hand. Now I think that if we loop in ensure_connected we should pass.

    def ensure_connected(self):
        while not self.is_fully_connected:
            room = self._straight_path_room()
            self.add_room(room)

Test passes. Commit: test and fix ensure_connected.

We’ll call that done.

Summary

Hard to know what to call that. I thought there was a defect, showed the defect, fixed it. It has been in there for a while, and I’m not sure but I’ve probably mentioned before that it seemed iffy.

Anyway, one more step forward. See you next time!