Skip to content

Instantly share code, notes, and snippets.

@yoshikischmitz
Last active January 1, 2016 02:09
Show Gist options
  • Save yoshikischmitz/8077793 to your computer and use it in GitHub Desktop.
Save yoshikischmitz/8077793 to your computer and use it in GitHub Desktop.
Ruby implementation of a simple cellular automata simulator. Gosu is used just for drawing, the CellMap class doesn't have any gosu specific code so it's very portable. Following this tutorial: http://gamedevelopment.tutsplus.com/tutorials/cave-levels-cellular-automata--gamedev-9664
require 'gosu'
class CellMap
include Enumerable
def initialize(x, y, chance_to_start_alive)
@map = Array.new
a = Random.new()
x.times do
column = Array.new(y)
y.times do |index|
if a.rand() < chance_to_start_alive
column[index] = true
end
end
@map << column
end
end
def count_alive_neighbours(x, y)
count = 0
(-1..1).each do |i|
(-1..1).each do |j|
neighbour_x = x + i
neighbour_y = y + j
if i == 0 and j == 0
elsif neighbour_x < 0 or neighbour_y < 0 or neighbour_x >= @map.length or neighbour_y >= @map[0].length
count += 1
elsif @map[neighbour_x][neighbour_y] == true
count += 1
end
end
end
return count
end
def do_simulation_step(death_limit = 4, birth_limit = 4)
new_map = []
@map.length.times do |x|
new_row = []
@map[0].length.times do |y|
nbs = count_alive_neighbours(x, y)
if @map[x][y]
if nbs < death_limit
new_row << false
else
new_row << true
end
else
if nbs > birth_limit
new_row << true
else
new_row << false
end
end
end
new_map << new_row
end
@map = new_map
end
def [](y)
@map[y]
end
def height
return @map.length
end
def width
return @map[0].length
end
end
class GameWindow < Gosu::Window
def initialize
super 1920, 1080, false
@width = 300
@height = 300
@chance_to_start_alive = 0.45
@cellmap = CellMap.new(@width, @height, @chance_to_start_alive)
@last_step = Gosu::milliseconds
end
def update
if button_down? Gosu::KbSpace and Gosu::milliseconds - @last_step > 100
@last_step = Gosu::milliseconds
@cellmap.do_simulation_step
puts "one step close to the edge, I'm about to break!"
elsif button_down? Gosu::KbEscape
puts "new map"
@cellmap = CellMap.new(@width, @height, @chance_to_start_alive)
end
end
def draw_cell(x, y, width, height)
color = Gosu::Color::WHITE
x += x * height
y += y * width
draw_quad(x , y, color,
x, y + width, color,
x + height, y, color,
x + height, y + width, color)
end
def draw
@cellmap.height.times do |index_x|
@cellmap.width.times do |index_y|
if @cellmap[index_x][index_y] == true
draw_cell(index_x, index_y, 2, 2)
end
end
end
end
end
window = GameWindow.new
window.show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment