Skip to content

Instantly share code, notes, and snippets.

@cjheath
Created April 2, 2014 10:43
Show Gist options
  • Save cjheath/9931773 to your computer and use it in GitHub Desktop.
Save cjheath/9931773 to your computer and use it in GitHub Desktop.
Conways game of Life, implemented without using a finite-sized world or "each"
class Cell
Directions = [
[-1,1], [0,1], [1,1],
[-1,0], [1, 0],
[-1,-1],[0,-1], [1,-1]
]
# Where am I?
def home
[@x, @y]
end
# Hello, world:
def initialize x, y
@x, @y = x, y
$world[home] = self
end
# Goodbye, cruel world:
def die
$world.delete home
end
# My neighbour in the given direction:
def neighbour direction
$world[location direction]
end
# Address of my neighbour in the given direction:
def location direction
[@x+direction[0], @y+direction[1]]
end
# Count of my neighbours:
def adjacent
Cell.adjacent home
end
# Count of the neighbours of the specified location:
def self.adjacent location
Directions.inject(0) do |count, direction|
loc = [location[0]+direction[0], location[1] + direction[1]]
count += 1 if $world[loc]
count
end
end
# What does this cell contribute to the next generation?
def evolution
if [2, 3].include?(adjacent)
[]
else
[proc{die}]
end +
Directions.inject([]) do |actions, direction|
loc = location(direction)
if Cell.adjacent(loc) == 3
actions << proc {
Cell.new(*loc) unless $world[loc]
}
end
actions
end
end
end
$world = {}
def $world.inspect
ys = keys.map{|l| l[1]}.uniq.sort
ys.map do |y|
xs = keys.select{|k| k[1] == y}.map{|l| l[0]}.sort
"#{y}: #{xs}"
end*"\n"
end
def $world.evolve
evolution = $world.values.map(&:evolution).flatten.map(&:call)
end
initial = [[0, 0], [0, 1], [0, 2]]
initial.map do |loc|
Cell.new(*loc)
end
10.times do |generation|
puts "Generation #{generation}"
p $world
$world.evolve
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment