# Re: SimFrost (#117)

**URL:** <https://www.ruby-forum.com/t/re-simfrost-117/88727>\
**Category:** Ruby\
**Created:** [March 13, 2007, 9:16pm UTC](https://www.ruby-forum.com/t/re-simfrost-117/88727 "2007-03-13T21:16:43Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [March 13, 2007, 9:16pm UTC](https://www.ruby-forum.com/t/re-simfrost-117/88727/1 "2007-03-13T21:16:43Z")

</div>

# [http://davidtran.doublegifts.com/blog/?p=10](http://davidtran.doublegifts.com/blog/?p=10)

class SimFrost

STATUS = [:VACUUM, :VAPOR, :ICE]

attr\_reader :ticks, :width, :height, :grid

def initialize(width, height, vapor\_chance=0.5)  
raise “width must be even and \>= 2” unless (width % 2 == 0) &&  
(width \>= 2)  
raise “height must be even and \>= 2” unless (height % 2 == 0) &&  
(height \>= 2)  
@width = width  
@height = height  
@grid = Array.new(@height) do  
Array.new(@width) { rand \< vapor\_chance ? :VAPOR : :VACUUM }  
end  
@grid[@height / 2][@width / 2] = :ICE  
@ticks = 0  
end

def tick  
shift unless (@ticks % 2 == 0)  
(0…@height).step(2) do |r|  
(0…@width).step(2) do |c|  
cells = [[r,c], [r,c+1], [r+1,c], [r+1,c+1]]  
if cells.any? { |y, x| @grid[y][x] == :ICE }  
cells.each { |y, x| @grid[y][x] = :ICE if @grid[y][x] ==  
:VAPOR }  
else  
cells\_rotate = rand(2).zero?   
? [cells[2], cells[0], cells[3], cells[1]]   
: [cells[1], cells[3], cells[0], cells[2]]  
rotate\_values = cells\_rotate.map { |y,x| @grid[y][x] }  
cells.each\_with\_index { |(y,x), i| @grid[y][x] =  
rotate\_values[i] }  
end  
end  
end  
unshift unless (@ticks % 2 == 0)  
@ticks = @ticks + 1  
@grid  
end

def done?  
not @grid.flatten.include?(:VAPOR)  
end

private

def shift  
@grid \<\< @grid.shift  
@grid.each { |row| row \<\< row.shift }  
end

def unshift  
@grid.unshift(@grid.pop)  
@grid.each { |row| row.unshift(row.pop) }  
end  
end

if **FILE** == $0  
if ARGV.size \< 3  
puts “Usage: #$0 gif\_file\_name width height [vapor\_chance]”  
exit  
end

file\_name = ARGV[0]  
width = ARGV[1].to\_i  
height = ARGV[2].to\_i  
vapor\_chance = ARGV[3] ? ARGV[3].to\_f : 0.5

require ‘RMagick’  
ICE\_COLOR = ‘blue’  
imageList = Magick::ImageList.new  
simFrost = SimFrost.new(width, height, vapor\_chance)  
while (not simFrost.done?) do  
image = Magick::Image.new(width, height)  
grid = simFrost.tick  
(0…height).each do |y|  
(0…width).each do |x|  
image.pixel\_color(x, y, ICE\_COLOR) if grid[y][x] == :ICE  
end  
end  
imageList \<\< image  
end  
imageList.write(file\_name)  
end
