# Ported from http://arthurtw.github.io/2015/01/12/quick-comparison-nim-vs-rust.html struct ANSI def initialize(@io : IO) end def clear @io << "\e[2J" end def pos(x, y) @io << "\e[" << x << ';' << y << 'H' end end class IO def ansi ANSI.new self end end struct ConwayMap WIDTH = 40 HEIGHT = 30 include Math @map : Array(Array(Bool)) def initialize(pattern) @map = Array.new(HEIGHT) { Array.new(WIDTH, false) } ix = min WIDTH, pattern.max_of(&.size) iy = min HEIGHT, pattern.size dx = (WIDTH - ix) // 2 dy = (HEIGHT - iy) // 2 iy.times do |y| ix.times do |x| if x < pattern[y].size && !pattern[y][x].whitespace? @map[y + dy][x + dx] = true end end end end def next old_map = @map.clone HEIGHT.times do |i| WIDTH.times do |j| nlive = 0 max(i - 1, 0).upto(min(i + 1, HEIGHT - 1)) do |i2| max(j - 1, 0).upto(min(j + 1, WIDTH - 1)) do |j2| nlive += 1 if old_map[i2][j2] && (i2 != i || j2 != j) end end if @map[i][j] @map[i][j] = 2 <= nlive <= 3 else @map[i][j] = nlive == 3 end end end end def to_s(io) io.ansi.clear io.ansi.pos 1, 1 @map.each do |row| row.each do |cell| io << (cell ? "()" : ". ") end io.puts end end end PAUSE = 20.milliseconds DEFAULT_COUNT = 300 INITIAL_MAP = [ " 1 ", " 1 1 ", " 11 11 11", " 1 1 11 11", "11 1 1 11 ", "11 1 1 11 1 1 ", " 1 1 1 ", " 1 1 ", " 11 ", ] map = ConwayMap.new INITIAL_MAP spawn { gets; exit } 1.upto(DEFAULT_COUNT) do |i| puts map puts "n = #{i}\tPress ENTER to exit" sleep PAUSE map.next end