Cairoライブラリを利用して画像を出力できるようにしてみました。
もうすこし抽象化したいですが..
require 'cairo' class World def initialize(size) @map = Array.new(size, 0) @rule = Hash.new end def show @map.each do |cell| if cell == 0 print " " else print "X" end end puts end def cellNeighbors(idx) [ @map[idx-1], @map[idx], @map[(idx+1) % (@map.size)] ] end def getNextState(idx) neighbors = cellNeighbors(idx) nextState = @rule.fetch(neighbors,0) return nextState end def update newMap = [] (0..@map.size-1).each do |idx| newMap << (getNextState(idx)) end @map = newMap end def genRandom() (0..@map.size-1).each do |idx| @map[idx] = rand(2) end end def setCell(idx, n) @map[idx] = n end def setRule(rule, n) @rule[rule] = n end def genPng(size, n, cellSize = 5, filePath) format = Cairo::FORMAT_ARGB32 surface = Cairo::ImageSurface.new(format, size*cellSize, n*cellSize) context = Cairo::Context.new(surface) context.set_source_rgb(1, 1, 1) # 白 context.rectangle(0, 0, size*cellSize, n*cellSize) context.fill context.stroke context.set_source_rgb(0, 0, 0) (0..n-1).each do |col| self.update @map.each_with_index do |cell, idx| if cell == 0 context.rectangle(idx*cellSize, col*cellSize, cellSize, cellSize) context.fill context.stroke end end end surface.write_to_png(filePath) end private :cellNeighbors private :getNextState #Accessor attr_reader :map, :rule end def rule30(size,n) world = World.new(size) world.setCell(size/2,1) world.setRule([0,0,0],0) world.setRule([0,0,1],1) world.setRule([0,1,0],1) world.setRule([0,1,1],1) world.setRule([1,0,0],1) world.setRule([1,0,1],0) world.setRule([1,1,0],0) world.setRule([1,1,1],0) world.show (1..n).each do |x| world.update world.show end end def rule90(size,n) world = World.new(size) world.setCell(size/2,1) world.setRule([0,0,0],0) world.setRule([0,0,1],1) world.setRule([0,1,0],0) world.setRule([0,1,1],1) world.setRule([1,0,0],1) world.setRule([1,0,1],0) world.setRule([1,1,0],1) world.setRule([1,1,1],0) world.show (1..n).each do |x| world.update world.show end end def rule137(size,n) world = World.new(size) world.setCell(size/2,1) world.setRule([0,0,0],1) world.setRule([0,0,1],0) world.setRule([0,1,0],0) world.setRule([0,1,1],1) world.setRule([1,0,0],0) world.setRule([1,0,1],0) world.setRule([1,1,0],0) world.setRule([1,1,1],1) world.show (1..n).each do |x| world.update world.show end end def rule150(size,n) world = World.new(size) world.setCell(size/2,1) world.setRule([0,0,0],0) world.setRule([0,0,1],1) world.setRule([0,1,0],1) world.setRule([0,1,1],0) world.setRule([1,0,0],1) world.setRule([1,0,1],0) world.setRule([1,1,0],0) world.setRule([1,1,1],1) world.show (1..n).each do |x| world.update world.show end end def rule62(size,n) world = World.new(size) world.setCell(size/2,1) world.setRule([0,0,0],0) world.setRule([0,0,1],1) world.setRule([0,1,0],1) world.setRule([0,1,1],1) world.setRule([1,0,0],1) world.setRule([1,0,1],1) world.setRule([1,1,0],0) world.setRule([1,1,1],0) world.show (1..n).each do |x| world.update world.show end end def rule73(size,n) world = World.new(size) world.setCell(size/2,1) world.setRule([0,0,0],1) world.setRule([0,0,1],0) world.setRule([0,1,0],0) world.setRule([0,1,1],1) world.setRule([1,0,0],0) world.setRule([1,0,1],0) world.setRule([1,1,0],1) world.setRule([1,1,1],0) world.show (1..n).each do |x| world.update world.show end end def samplePng(fileName) world = World.new(100) world.setCell(100/2,1) world.setRule([0,0,0],1) world.setRule([0,0,1],0) world.setRule([0,1,0],0) world.setRule([0,1,1],1) world.setRule([1,0,0],0) world.setRule([1,0,1],0) world.setRule([1,1,0],1) world.setRule([1,1,1],0) world.genPng(100, 100, 3, fileName) end samplePng("hoge.png")
生成される画像は、こんな感じ。Rule73ですね。