#!/usr/bin/ruby # Game of Life # basic (aka very inefficient) implementation # copyright 2008 Yoann Guillot # license: GPLv2 class World attr_accessor :w, :h, :table def initialize(w=32, h=w) @emptyl = "\0"*((w+7)/8) @w, @h = w, h @table = Array.new(h) { @emptyl.dup } @clear = `clear` end def iter counts = Array.new(h) { [] } @h.times { |y| @w.times { |x| counts[y][x] = countnb(x, y) } } puts counts.map { |c| c.join(' ') } if $DEBUG #@table = Array.new(h) { @emptyl.dup } @h.times { |y| @w.times { |x| case counts[y][x] when 3: set(x, y, true) when 2 else set(x, y, false) end } } end def countnb(x, y) n = 0 (-1..1).each { |i| n += 1 if get(x+i, y-1) n += 1 if get(x+i, y+1) n += 1 if i != 0 and get(x+i, y) } n end # true/false def get(x, y) x %= @w y %= @h @table[y][x/8][x%8] != 0 end alias [] get def set_intable(t, x, y, v) x %= @w y %= @h if v t[y][x/8] |= 1<<(x%8) else t[y][x/8] &= 0xff ^ (1<<(x%8)) end end def set(x, y, v) set_intable(@table, x, y, v) end alias []= set def display puts @clear, @table.map { |r| r.unpack('b*').first.tr('01', ' x').gsub(/(.)/, ' \1') } #puts '-'*@w*2 end def finished? @table.all? { |r| r == @emptyl } end def run while not finished? display iter end display end def randomize @h.times { |y| @w.times { |x| set(x, y, rand(2) == 1) } } end end w = World.new(ARGV.empty? ? 32 : ARGV.shift.to_i) w.randomize #w[1, 0] = w[2, 1] = w[0, 2] = w[1, 2] = w[2, 2] = true w.run