Search code examples
pythonnested-listsconways-game-of-life

Is there a way to prevent a program from checking values that are outside of a list's range?


So I'm working on an implementation of Conway's Game of Life in Python and I have most of my code written. For the most part it works; when I run it, the board appears and the cells are randomized, but there's one problem. I have a loop that checks the status of the 8 cells around each cell in the board, but the program comes to a complete stop at the first check, (the cell in the top-left corner), because 5 of the 8 cells are outside of the grid. I don't know how to limit this, or to make it check ONLY the cells INSIDE the grid. Does anyone have any idea on how I could approach this?

My board is organized in columns, (height) and number of columns (width). All of this is organized in a list of lists called currentCells and nextCells.

This is my code for checking living neighbors of each cell:

LivingNeighbors = 0 #set to zero so it can change based on the conditions
    
    for x in range( WIDTH ):
      for y in range( HEIGHT ):
        # Count number of living neighbors:
        aboveLeft = currentCells[x - 1] [y - 1]
        above = currentCells[x] [y - 1]
        aboveRight = currentCells[x + 1] [y - 1]
        left = currentCells[x - 1] [y]
        right = currentCells[x + 1] [y]
        bottomLeft = currentCells[x - 1] [y + 1]
        bottom = currentCells[x] [y + 1]
        bottomRight = currentCells[x + 1] [y + 1]
        if aboveLeft == '#':
          LivingNeighbors += 1
        if above == '#':
          LivingNeighbors += 1
        if aboveRight == '#':
          LivingNeighbors += 1
        if left == '#':
          LivingNeighbors += 1
        if right == '#':
          LivingNeighbors += 1
        if bottomLeft == '#':
          LivingNeighbors += 1
        if bottom == '#':
          LivingNeighbors += 1
        if bottomRight == '#':
          LivingNeighbors += 1

Solution

  • You can use logical operators to check whether you're in range before trying to access the neighbor.

            aboveLeft = x > 0 and y > 0 and currentCells[x - 1] [y - 1]
            above = y > 0 and currentCells[x] [y - 1]
            aboveRight = x < len(currentCells)-1 and y > 0 and currentCells[x + 1] [y - 1]
    

    and similarly for all the rest of the variables.

    Even better would be to use a loop rather than 8 different variables.

    for dx in (-1, 0, 1):
        for dy in (-1, 0, 1):
            if not (dx == 0 and dy == 0): # don't count the cell itself
                new_x = x + dx
                new_y = y + dy
                if 0 <= new_x < len(currentCells) and 0 <= new_y < len(currentCells[x]): # check if neighbor is in range
                    livingNeighbors += currentCells[new_x][new_y] == '#'