Futzing
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!