Ruby Game of Life with matrices A little while ago I wrote this implementation of Conway's Game of Life in Ruby. It's based on this Game of Life in APL video, which I think is rather elegant, though a bit dense. Feel free to give feedback on any aspect of the program, but the parts I most care about are readability and the way I work with matrices.

Unlike most implementations, the neighbor count used to determine who's alive in the next generation includes self (the cell who's neighbors we are counting). This technique is used in the APL version as well and allows us to express the rules of the game in a more concise manner than normal: i.e. a cell in the next generation is alive if its neighbor count including self is three or if it was alive in the last generation and its neighbor count including self is four. 

The program currently monkey-patches Matrix, which I'm not thrilled about. I'm pretty sure Matrix#translate can be removed in favor of some sort of matrix math that would do the equivalent, but I'm not familiar enough with the subject to know how to do this well.

It would also probably be nice to blank the screen without shelling out.

The program requires Ruby 1.9 or later.

#!/usr/bin/env ruby
# encoding: utf-8

require 'matrix'

class Matrix
  def translate(row_count, col_count)
    Matrix[
      *row_vectors.map do |row|
        row.to_a.rotate(row_count)
      end.rotate(col_count)
    ]
  end
end

class Board
  attr_reader :width, :height

  def self.random(size)
    board = Matrix.build(size) { rand(10) == 0 ? 1 : 0 }
    new(board)
  end

  def self.parse(board_string)
    new(Matrix[board_string.split("\n").map { |row| row.split.map(&amp;:to_i) }])
  end

  def initialize(board)
    @width = board.column_size
    @height = board.row_size
    @board = board
  end

  def next
    board_state = neighbor_counts.map.with_index do |count, idx|
      count == 3 || count == 4 &amp;&amp; @board[idx / width, idx % width] == 1 ? 1 : 0
    end

    Board.new(board_state)
  end

  def to_s
    @board.row_vectors.map do |row|
      row.map do |n|
        n == 1 ? "B" : "·"
      end.to_a.join(" ")
    end.join("\n")
  end

  def neighbor_counts
    [-1,0,1].product([-1,0,1]).map do |row, col|
      @board.translate(row, col)
    end.reduce(:+)
  end
end

if __FILE__ == $0
  b = Board.random(40)
  system("clear")

  loop do
    puts b
    sleep 0.2
    system("clear")
    b = b.next
  end
end
Instead of magic numbers, extract them to either explaining variables or constants.
For example, in neighbor_counts, what are -1, 0, and 1?
People who are familiar with the GoL might know what you're trying to do, but assume you're passing this off to someone who is new to the GoL and doesn't know what these constants represent.