Errors with Conway's Game of Life


#1

Hi,

I’m trying to reproduce the game of life but I have several problems:
thread 'main' panicked at 'attempt to subtract with overflow' with the line if grid[x-1][y-1] == 1 {

  • Is there a simple way to detect if a cell exist (something like isset() in PHP for example) ? I’d like to avoid the verification of x and y for every step.

  • How can I use match for the grid verification in order to avoid the if ?

      extern crate rand;
    
      use rand::Rng;
    
      fn main() {
          const MAX:usize = 10;
          let mut grid: [[i32; MAX]; MAX] = [[0; MAX]; MAX];
    
          for row in grid.iter_mut() {
              for cell in row.iter_mut() {
                  *cell = rand::thread_rng().gen_range(0,2);
                  print!("{}",cell);
              }
              print!("\n");
          }
          //println!("{:?}", grid)
          let mut alive: i32 = 0;
          for x in 0..9 {
              for y in 0..9 {
                  if grid[x-1][y-1] == 1 {
                      alive += 1;
                  }
                  //left
                  if grid[x-1][y] == 1 {
                      alive += 1;
                  }
                  //top-left
                  if grid[x-1][y+1] == 1 {
                      alive += 1;
                  }
                  //bottom
                  if grid[x][y-1] == 1 {
                      alive += 1;
                  }
                  //right
                  if grid[x][y+1] == 1 {
                      alive += 1;
                  }
                  //bottom-right
                  if grid[x+1][y-1] == 1 {
                      alive += 1;
                  }
                  //right
                  if grid[x+1][y] == 1 {
                      alive += 1;
                  }
                  //top-right
                  if grid[x+1][y+1] == 1 {
                      alive += 1;
                  }
                  //alive
                  if alive == 3 && grid[x][y] == 0 {
                      grid[x][y] = 1;
                  }
                  //alive
                  if (alive == 3 || alive == 2) && grid[x][y] == 1 {
                      grid[x][y] = 1;
                  }
                  //dead
                  else{
                      grid[x][y] = 0;
                  }
              }
          }
      }

#2

Hi,

Looks like the issue is with your range 0..9. The start of the range is inclusive, so x and y start with a value of 0. You then subtract 1 and hit the panic. It’s important to note the panic comes from the subtraction operator itself, not the index operation for your grid array. The subtract operator panics because the data type chosen for x and y (based on the array indexing) is unsigned; usize.

IMHO, you don’t need to use match to workaround the overflow, or otherwise check for an existing cell. You just need to use a valid range like 1..10 (The end of the range is exclusive.)

edit: Hit reply too soon, whoops!


#3

Thanks but there is a problem, if I start with range 1…10 the first row and the first column will never be checked even if their state (life or death) should be able to change. In order to check cell’s state I need to check the 8 cells around every cell.
Then how can I fix the substraction error ?


#4

I think you only have two options, really. You can either keep the first row and column hidden from the display (to act as fall-through accumulators), or add a bunch of > 0 conditions to prevent the overflow from occurring. Since you don’t really want to do the latter, I offered the other solution. :slight_smile:

I would consider it along the same lines as a common memory/time trade-off. You don’t need this level of optimization for a Game of Life, but if it makes the code a bit cleaner, then it’s probably an acceptable compromise.


#5

I just noticed you are going to have the same problem with the + 1 overflowing the array length, too. So you’ll also need an extra hidden row and column on the ends. Or even more < MAX + 1 conditions sprinkled around.


#6

Alright, I will do this. Thanks for the answer