For a dungeon crawler, I have multiple game levels that can be navigated by using a 2d list as a grid. The dungeons are all unique objects with many attributes, including tuples representing interactive event locations.
def __init__(self):
super().__init__()
self.name = "The Catacombs"
self.level = 1
self.throne = (2, 3)
self.fountain = (3, 3)
self.teleporter = (4, 3)
self.pit = (2, 4)
....
The next part of the code exists as a player class function. The player's coordinates are stored as a tuple. If the player's coordinates exist as a key in a dictionary, a corresponding function is called..
def event_logic(self):
self.coordinates = (self.x, self.y)
event_dict = {self.dungeon.throne: self.throne_event,
self.dungeon.fountain: self.fountain_event,
self.dungeon.teleporter: self.teleporter_event,
self.dungeon.pit: self.pit_event
}
if self.coordinates in event_dict.keys():
event_function = (event_dict[self.coordinates])
return event_function()
The problem is that this only allows me to have one such event per level; I am using one tuple for each key. I want to have a few pits to fall into and a few thrones to sit on or pry gems from. So, after realizing that lists cannot be used as keys, I tried using a tuple of tuples, like, self.throne = ((2,3), (18,4)....)
to allow me to have multiple events throughout, but that does not work, because the player's coordinates do not exactly match the tuple of tuples.
I need a way to determine if 1 tuple exists within multiple tuples within the dictionary keys to call the corresponding function. If this is not possible, I need an alternative way..
CodePudding user response:
Using dictionary keys like this defeats the quick access purpose of a dictionary.
You'd be better having a dictionary of all events based on co-ordinates allowing you to easily look up multiple events e.g.:
self.locations = {}
self.location[(2, 3)] = self.throne_event
self.location[(2, 6)] = self.teleporter_event
self.location[(3, 5)] = self.teleporter_event
if self.coordinates in self.locations():
location_event = self.locations.get(self.coordinates)
This limits you to one event for location. To allow multiple, store a list at each co-ordinate:
location_events = [
self.throne_event,
self.fountain_event
]
self.locations[(2, 3)] = location_events
Then to action the player's coordinates:
events_at_coordinate = self.locations.get(self.coordinates)
for event in events_at_coordinate:
# do what you would do with your location event(s)
CodePudding user response:
it may be easier to not directly work on individual type of items, but rather store the list of items present at each location. Example:
def __init__(self):
super().__init__()
self.name = "The Catacombs"
self.level = 1
self.pois = [
{"type": "throne", "positions": [(2, 3), (4,5)]},
{"type": "pit", "positions": [(2, 4), (4,4)]}
]
Then you can just loop other these to build a second-hand variable:
position_to_items = {}
for item_props in self.pois:
for position in item_props["positions"]:
if position in position_to_items:
position_to_items[position].append(item_props["type"])
else:
position_to_items[position] = [item_props["type"]]
Then, given a position (tuple), you'll directly get the list of items present in the room.