I had a few moments and decided to do a round room. At which point I realized that something can be improved.

This is an after-action report, not contemporaneous. I wrote a test:

    def test_round_room(self):
        space = CellSpace(64, 56)
        maker = RoomMaker(space)
        room_start = space.at(30,30)
        room = maker.round(8, room_start)
        for c in room:
            assert c.distance(room_start) <= 8
        assert len(room.cells) == 197

I didn’t fill in the 197, that’s after the fact. We needed distance in Cell, as we have manhattan distance but not geometric:

    def distance(self, target):
        return math.hypot(self.x - target.x, self.y - target.y)

I didn’t know about math.hypot, but PyCharm suggested it. Good enough.

The code for the round is:

class RoomMaker:
    def __init__(self, space: CellSpace):
        self.space = space

    def cave(self, number_of_cells: int, origin: Cell, name =''):
        return CaveRoomMaker(self.space).cave(number_of_cells, origin, name)

    def diamond(self, number_of_cells: int, origin: Cell, name =''):
         return DiamondRoomMaker(self.space).diamond(number_of_cells, origin, name)

    def round(self, radius:int, origin: Cell, name ='round'):
        return RoundRoomMaker(self.space).round(radius, origin, name)

class RoundRoomMaker:
    def __init__(self, space: CellSpace):
        self.space = space
        self.cells:list[Cell] = []

    def round(self, radius:int, origin: Cell, name =''):
        for c in origin.generate(lambda c: c.is_available and origin.distance(c) <= radius):
            self.cells.append(c)
        return Room(self.cells, origin, name)

So easy enough. I can’t think offhand how to early exit the loops, so it’ll be checking far more cells than need be. It’s essentially building a diamond and cutting off the points to make it more round. Possibly I can work up some scheme where once some maximum radius has shown up and been trimmed locally, we can stop early.

Here are two pictures, one with just round rooms and one with a mixture of all types:

some round rooms

mixed round, diamond, and cave rooms

Just Cells!

In doing this, I realized that there is no real point to making the Room inside the specialized classes. They could instead just create a list of cells and return that to the RoomMaker, who will make the actual Room. Simpler, fewer parameters, fewer classes who have to know how to make a Room instance, less duplication, almost certainly better.

We try to learn whenever we code. This may be such a time.

Let’s do that another time. This was just an afternoon diversion. See you next time!