Skip to content

Instantly share code, notes, and snippets.

@ambethia
Last active February 4, 2022 18:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ambethia/1429621 to your computer and use it in GitHub Desktop.
Save ambethia/1429621 to your computer and use it in GitHub Desktop.
My implementation of Conway's Game of Life
# Run this:
# ruby < <(curl -s https://gist.githubusercontent.com/ambethia/1429621/raw/life.rb)
require 'curses'
class Life
extend Curses
CELL_CHAR = "*"
def initialize(x, y)
@columns = x
@rows = y
@cells = {}
end
def evolve
@cells = {}.tap do |generation|
@columns.times do |x|
@rows.times do |y|
generation[[x,y]] = true if will_live? x, y
end
end
end
end
def will_live? *position
neighbors = sum_of_neighbors(*position)
if alive?(*position)
neighbors == 2 || neighbors == 3
else
neighbors == 3
end
end
def alive? *position
@cells[position]
end
def seed! *coordinates
coordinates.each do |position|
@cells[position] = true
end
end
private
def sum_of_neighbors x, y
neighbors = 0
(-1..1).each do |u|
(-1..1).each do |v|
neighbors += 1 if alive?(x+u, y+v) && [u,v] != [0,0]
end
end
neighbors
end
def self.evolve
begin
noecho
init_screen
curs_set 0
stdscr
life = new(cols, lines)
# simple shape translated to the center
simple_shape = [[0, 0], [0, -1], [1, 0], [1, 1], [-1, 0]]
simple_shape.map! { |coords| [coords[0]+(cols/2), coords[1]+(lines/2)] }
life.seed! *simple_shape
loop do
clear
cols.times do |x|
lines.times do |y|
if life.alive? x, y
setpos y, x
addstr CELL_CHAR
end
end
end
refresh
sleep(0.1)
life.evolve
end
ensure
close_screen
end
end
end
if ENV['TM_RUBY']
require 'test/unit'
class LifeTest < Test::Unit::TestCase
def setup
@life = Life.new(2,2)
end
def test_a_living_cell_should_not_survive_with_no_neighbors
@life.seed! [0,0]
assert !@life.will_live?(0,0)
end
def test_a_living_cell_should_not_survive_with_one_neighbor
@life.seed! [0,0], [0,1]
assert !@life.will_live?(0,0)
end
def test_a_living_cell_should_survive_with_two_neighbors
@life.seed! [0,0], [0,1], [1,1]
assert @life.will_live?(0,0)
end
def test_a_living_cell_should_survive_with_three_neighbors
@life.seed! [0,0], [0,1], [1,1], [1,0]
assert @life.will_live?(0,0)
end
def test_a_living_cell_should_not_survive_with_four_neighbors
@life.seed! [0,0], [0,1], [1,1], [1,0], [1,-1]
assert !@life.will_live?(0,0)
end
def test_a_dead_cell_should_live_with_three_neighbors
@life.seed! [0,1], [1,1], [1,0]
assert @life.will_live?(0,0)
end
def test_a_dead_cell_should_not_live_with_two_neighbors
@life.seed! [0,1], [1,1]
assert !@life.will_live?(0,0)
end
def test_a_dead_cell_should_not_live_with_four_neighbors
@life.seed! [0,1], [1,1], [1,0], [1,-1]
assert !@life.will_live?(0,0)
end
end
else
Life.evolve
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment