Last active
February 4, 2022 18:05
-
-
Save ambethia/1429621 to your computer and use it in GitHub Desktop.
My implementation of Conway's Game of Life
This file contains hidden or 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
# 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 [email protected]_live?(0,0) | |
end | |
def test_a_living_cell_should_not_survive_with_one_neighbor | |
@life.seed! [0,0], [0,1] | |
assert [email protected]_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 [email protected]_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 [email protected]_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 [email protected]_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