title: Logic Error in Chessboard Virus Simulation
body: <p>The Chessboard virus problem is similar to Conway's &quot;Game of Life&quot;. The rule is that any two squares with infected neighbours will become infected.</p>
  <p>I have tried to implement the simulation in Python, but there is a logic error. I think what is happening is that the board is being updated within a single round, so intermediate steps are missed. For example, with</p>
  <pre><code>grid = [
      [0, 1, 0, 1],
      [1, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0]
  ]
  </code></pre>
  <p>I get following output:</p>
  <pre><code>Initial State of board:
  
   0 1 0 1
   1 0 0 0
   0 0 0 0
   0 0 0 0
  
  State 2 of board:
  
   1 1 1 1
   1 1 1 1
   0 0 0 0
   0 0 0 0
  
  Infinite loop entered.
  </code></pre>
  <p>The first round should only show</p>
  <pre><code>1 1 1 1
  1 1 0 0
  0 0 0 0
  0 0 0 0
  </code></pre>
  <p>Unless I am mistaken.</p>
  <p>Can anyone help me to fix the logic error please?</p>
  <pre><code>grid = [
      [0, 1, 0, 1],
      [1, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0]
  ]
  
  
  def write(grid):
      &quot;&quot;&quot;
      Writes the lists of lists of booleans
      in grid using 0 for False and 1 for True.
      &quot;&quot;&quot;
      for row in grid:
          for item in row:
              print(f&quot; {item}&quot;, end=&quot;&quot;)
          print()
  
  
  def neighbors(grid, i, j):
      &quot;&quot;&quot;
      Returns the number of live cells
      next to grid[i][j]. Does not include diagonals.
      &quot;&quot;&quot;
      num_neighbours = 0
      if i &gt; 0:
          if grid[i - 1][j]:
              num_neighbours = num_neighbours + 1
      if i &lt; len(grid) - 1:
          if grid[i + 1][j]:
              num_neighbours = num_neighbours + 1
      if j &gt; 0:
          if grid[i][j - 1]:
              num_neighbours = num_neighbours + 1
      if j &lt; len(grid[i]) - 1:
          if grid[i][j + 1]:
              num_neighbours = num_neighbours + 1
      print(num_neighbours)
      return num_neighbours
  
  
  def update(grid):
      &quot;&quot;&quot;
      Applies the rule of the chessboard virus to grid
      and returns a new grid.
      &quot;&quot;&quot;
      new_board = grid[:]
      for i in range(len(grid)):
          for j in range(len(grid[i])):
              num_neighbours = neighbors(grid, i, j)
              if num_neighbours &gt;= 2:
                  new_board[i][j] = 1
      return new_board
  
  
  def check_all_ones(a):
      return not any(c != 1 for r in a for c in r)
  
  
  def main():
      &quot;&quot;&quot;
      Runs the simulation.
      &quot;&quot;&quot;
      global grid
      grid = grid
      print(&quot;Initial State of board:&quot;)
      print()
      write(grid)
      state_num = 1
      while True:
          last_grid = grid[:]  # Clone grid.
          grid = update(grid)
          state_num = state_num + 1
          print()
          print(f&quot;State {state_num} of board:&quot;)
          print()
          write(grid)
          if check_all_ones(grid):
              print()
              print(&quot;Virus has spread to whole board.&quot;)
              break
          if grid == last_grid:
              print()
              print(&quot;Infinite loop entered.&quot;)
              break
  
  
  if __name__ == &quot;__main__&quot;:
      main()
  
  </code></pre>