Last active
January 1, 2016 02:09
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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