Modifying print_map to show shorthands

I’m trying to get this method to show the shorthand of a given unit instead of just a space where a unit would be. I’ve modified it to the following so far:

def print_map(self):
        """Prints an ASCII version of the current game map for debug purposes"""
        for y in range(28):
            for x in range(28):
                node = self.game_map[x][28 - y - 1]
                if not node.blocked and not node.pathlength == -1:
                    self._print_justified(node.pathlength)
                elif node.blocked:
                    location = [x, 28-y-1]
                    sys.stderr.write(self.game_map.__getitem__(location).shorthand)
                else:
                    sys.stderr.write("   ")
            debug_write("")

However, I get the following error which I can’t quite make sense of:
TypeError: list indices must be integers or slices, not list
What is my problem here?

Also, when using the original definition, I get the following error:
AttributeError: 'ShortestPathFinder' object has no attribute 'game_map'
Where is this one coming from? I don’t think that this error should occur in the original definition.

Regarding your first error:

self.game_map.__getitem__(location) returns a list of units at that location (may be empty) instead of a single unit. This explains the TypeError, you are trying to call .shorthand on a list, not a unit like you thought. You will need to decide how you want to handle outputting this, but one option if you know the units are the same is just (this is only for displaying data):

units_at_loc = game_map[location[0], location[1]]
if len(units_at_loc) > 0:
	sys.stderr.write(units_at_loc[0].shorthand)

Regarding your second error, if you look at the ShortestPathFinder class you’ll notice that self.game_map is not created until navigate_multiple_endpoints is called. My guess would be you are trying to call print_map() before this function has been called, hence the AttributeError.

I would recommend making a new printing function or something since that print_map() is specific to the navigation class and displays data relevant to it. You could create a custom one in the GameState class (or anywhere you want really) that uses the game_map from there since you are displaying data relevant to that class.

1 Like

I tried your approach, but I’m still getting the same TypeError. It seems to be a problem with the argument passed.

Ah, sorry about that, I have changed my configuration slightly so I can use that syntax.

The correct code would be:

newx, newy = location
units_at_loc = self.game_map[newx][newy]
if len(units_at_loc) > 0:
	sys.stderr.write(units_at_loc[0].shorthand)

However, this still won’t work because this returns a Node object. Take a look at this part of the game_map constructor for the ShortestPathFinder class:

self.game_map = [[Node() for x in range(self.game_state.ARENA_SIZE)] for y in range(self.game_state.ARENA_SIZE)]

Thus, this is not the same game_map you use in your GameState object. to use the one you want, you’ll have to pass an argument to the function containing the game_map object you want.

So the function header would become (excluding the other code in the …):

def print_map(self, game_state_map):
    ...
    newx, newy = location
    units_at_loc = game_state_map[newx][newy]
    if len(units_at_loc) > 0:
	sys.stderr.write(units_at_loc[0].shorthand)

Where you have to pass the game_map as the parameter.

2 Likes