Home > Enterprise >  Find tuple within tuple as a dictionary key
Find tuple within tuple as a dictionary key

Time:09-07

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.

  • Related