def game_of_life(name, size, generations, initial_life=nil)
  board = new_board size
  seed board, size, initial_life
  print_board board, name, 0
  reason = generations.times do |gen|
    new = evolve board, size
    print_board new, name, gen+1
    break :all_dead if barren? new, size
    break :static   if board == new
    board = new
  end
  if    reason == :all_dead then puts 
  elsif reason == :static   then puts 
  else                           puts 
  end
  puts
end

def new_board(n)
  Array.new(n) {Array.new(n, 0)}
end

def seed(board, n, points=nil)
  if points.nil?
    
    indices = []
    n.times {|x| n.times {|y| indices << [x,y] }}
    indices.shuffle[0,10].each {|x,y| board[y][x] = 1}
  else
    points.each {|x, y| board[y][x] = 1}
  end
end

def evolve(board, n)
  new = new_board n
  n.times {|i| n.times {|j| new[i][j] = fate board, i, j, n}}
  new
end

def fate(board, i, j, n)
  i1 = [0, i-1].max; i2 = [i+1, n-1].min
  j1 = [0, j-1].max; j2 = [j+1, n-1].min
  sum = 0
  for ii in (i1..i2)
    for jj in (j1..j2)
      sum += board[ii][jj] if not (ii == i and jj == j)
    end
  end
  (sum == 3 or (sum == 2 and board[i][j] == 1))? 1: 0
end

def barren?(board, n)
  n.times {|i| n.times {|j| return false if board[i][j] == 1}}
  true
end

def print_board(m, name, generation)
  puts 
  m.each {|row| row.each {|val| print }; puts}
end

game_of_life , 3, 2, [[1,0],[1,1],[1,2]]
game_of_life , 4, 4, [[1,0],[2,1],[0,2],[1,2],[2,2]]
game_of_life , 5, 10