Search code examples
pythonconventionstry-except

Being less repetitive with try - except


Context

The goal of the script is to simulate a chain reaction of explosions given a map where any positive integer is a bomb, and its value is its magnitude. If the explosion hits another bomb, it causes that bomb to explode.

Problem

In my code I repeatedly use the try - except blocks to verify that the coordinate is on the map. I want to know how I could avoid doing that.

Code

def chain_reaction(map, coord):

    explosion = map[coord[0]][coord[1]]
    map[coord[0]][coord[1]] = 0

    for i in range(1, explosion + 1):
        try:
            if map[coord[0] + i][coord[1]] != 0:
                chain_reaction(map, (coord[0] + i, coord[1]))
        except IndexError:
            pass

        try:
            if map[coord[0] - i][coord[1]] != 0:
                chain_reaction(map, (coord[0] - i, coord[1]))
        except IndexError:
            pass

        try:
            if map[coord[0]][coord[1] + i] != 0:
                chain_reaction(map, (coord[0],coord[1] + i))
        except IndexError:
            pass

        try:
            if map[coord[0]][coord[1] - i] != 0:
                chain_reaction(map, (coord[0], coord[1] - i))
        except IndexError:
            pass

        try:
            map[coord[0] + i][coord[1]], map[coord[0] - i][coord[1]] = 0, 0
            map[coord[0]][coord[1] + i], map[coord[0]][coord[1] - i] = 0, 0
        except IndexError:
            pass

    return map

map = [[0,1,0,2], [3,0,1,1], [0,1,0,1], [0,0,2,0], [1,0,0,0]]

chain_reaction(map, (3,2))

What would be the optimal / best way to solve this issue?


Solution

  • Refactor the common code to a helper function. Note that map is the name of a built-in. That should be changed as well. Also, isn't the final try unnecessary? chain_reaction would already have set those locations to zero...

    def check(map, coord):
        try:
            if map[coord[0]][coord[1]] != 0:
                chain_reaction(map, (coord[0], coord[1]))
        except IndexError:
            pass
    
    def chain_reaction(map, coord):
    
        explosion = map[coord[0]][coord[1]]
        map[coord[0]][coord[1]] = 0
    
        for i in range(1, explosion + 1):
            check(map, (coord[0] + i, coord[1]))
            check(map, (coord[0] - i, coord[1]))
            check(map, (coord[0],coord[1] + i))
            check(map, (coord[0], coord[1] - i))
    
            #try:
            #    map[coord[0] + i][coord[1]], map[coord[0] - i][coord[1]] = 0, 0
            #    map[coord[0]][coord[1] + i], map[coord[0]][coord[1] - i] = 0, 0
            #except IndexError:
            #    pass
    
        return map
    
    map = [[0,1,0,2], [3,0,1,1], [0,1,0,1], [0,0,2,0], [1,0,0,0]]
    
    chain_reaction(map, (3,2))