From: Simon Strandgaard Date: 2004-04-05T16:24:18+09:00 Subject: Re: mine.rb On Sun, 04 Apr 2004 02:32:43 -0800, Manny Swedberg wrote: [snip] > Anyone know of an easily-available, simple sample program that does > kind of the same thing? > Here is a smallish game-of-life I recently made.. no fancy colors.. Is that usable to you ? A sample output server> ruby gameoflife.rb lets play a game 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The implementation + testsuite... BTW: is under Ruby's license. server> wc -l gameoflife.rb test_gameoflife.rb 73 gameoflife.rb 108 test_gameoflife.rb 181 total server> expand -t2 gameoflife.rb module GameOfLife def determine_destiny(alive, count) unless alive return (count == 3) end (count == 2) or (count == 3) end def get(cells, y, x) return 0 if x < 0 or y < 0 return 0 if y >= cells.size row = cells[y] return 0 if x >= row.size row[x] end def count_neighbours(cells, x, y) n = 0 n += get(cells, y-1, x-1) n += get(cells, y-1, x) n += get(cells, y-1, x+1) n += get(cells, y, x-1) n += get(cells, y, x+1) n += get(cells, y+1, x-1) n += get(cells, y+1, x) n += get(cells, y+1, x+1) n end def lifecycle(cells) y = 0 next_cells = cells.map do |row| x = 0 next_row = row.map do |cell| n = count_neighbours(cells, x, y) x += 1 determine_destiny((cell != 0), n) ? 1 : 0 end y += 1 next_row end next_cells end end if $0 == __FILE__ puts "lets play a game" class Game include GameOfLife def initialize @cells = [ [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 0], [0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0] ] end def next @cells = lifecycle(@cells) end def inspect rows = @cells.map do |row| row.join(" ") end rows.join("\n") end end game = Game.new loop do p game gets game.next end end server> expand -t2 test_gameoflife.rb require 'test/unit' require 'gameoflife' class TestGameOfLife < Test::Unit::TestCase include GameOfLife def test_destiny_populated data = [ [0, false], [1, false], [2, true], [3, true], [4, false], [5, false], [6, false] ] input, expected = data.transpose actual = input.map do |count| determine_destiny(true, count) end assert_equal(expected, actual) end def test_destiny_empty data = [ [0, false], [1, false], [2, false], [3, true], [4, false], [5, false], [6, false] ] input, expected = data.transpose actual = input.map do |count| determine_destiny(false, count) end assert_equal(expected, actual) end def test_count_neighbours0 cells = [ [0, 0, 0], [0, 1, 0], [0, 0, 0] ] n = count_neighbours(cells, 1, 1) assert_equal(0, n) end def test_count_neighbours1 cells = [ [1, 0, 0], [0, 1, 1], [0, 1, 0] ] n = count_neighbours(cells, 1, 1) assert_equal(3, n) end def test_count_neighbours2 cells = [ [0, 1, 1], [1, 1, 1], [1, 1, 0] ] n = count_neighbours(cells, 1, 1) assert_equal(6, n) end def test_count_neighbours3 cells = [ [0, 1, 1], [1, 1, 1], [1, 1, 0] ] n = count_neighbours(cells, 0, 0) assert_equal(3, n) end def test_count_neighbours4 cells = [ [0, 1, 1], [1, 1, 1], [1, 1, 0] ] n = count_neighbours(cells, 2, 2) assert_equal(3, n) end def test_count_neighbours5 cells = [ [1, 0, 1, 0], [0, 1, 1, 1], [1, 0, 0, 1] ] n1 = count_neighbours(cells, 1, 1) n2 = count_neighbours(cells, 2, 1) assert_equal([4, 4], [n1, n2]) end def test_lifecycle1 cells = [ [0, 1, 1], [1, 1, 1], [1, 1, 0] ] expected_cells = [ [1, 0, 1], [0, 0, 0], [1, 0, 1] ] actual = lifecycle(cells) assert_equal(expected_cells, actual) end end require 'test/unit/ui/console/testrunner' Test::Unit::UI::Console::TestRunner.run(TestGameOfLife) server> -- Simon Strandgaard