Created
July 31, 2010 05:56
-
-
Save zrbecker/501813 to your computer and use it in GitHub Desktop.
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
Game Of Life in Ruby | |
initialize function gives a few options. You can specify the dimensions | |
of the board, and you can specify if you want the board to wrap around | |
to the other side. | |
evolve simply iterates though the state array and uses the rules to | |
determine if it should change states. | |
randomize_game_state is in a separate function, so it can easily be | |
called if desired. | |
is_alive returns false if you give it a cell off the board. Also you | |
can specify an origin cell and check a cell's state relative to it with | |
optional parameters. | |
count_neighbours simply counts all the alive cells around a particular | |
cell, using alive relative feature to simplify this. | |
update_dimensions if you set the state to an arbitrary array, this | |
method can be called to properly set the width and height. It uses the | |
smallest column height to avoid problems. |
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
class GameOfLife | |
attr_accessor :state | |
DEAD = 0 | |
ALIVE = 1 | |
def initialize(width, height = width, wrapped = true) | |
@wrapped = wrapped | |
randomize_game_state(width, height) | |
end | |
def evolve | |
# Copy game state | |
new_state = Marshal.load(Marshal.dump(@state)) | |
0.upto(@width - 1) do |x| | |
0.upto(@height - 1) do |y| | |
neighbours = count_neighbours(x, y) | |
if is_alive(x, y) and neighbours < 2 | |
new_state[x][y] = DEAD | |
elsif is_alive(x, y) and neighbours > 3 | |
new_state[x][y] = DEAD | |
elsif !is_alive(x, y) and neighbours == 3 | |
new_state[x][y] = ALIVE | |
end | |
end | |
end | |
@state = new_state | |
end | |
def randomize_game_state(width, height) | |
@width = width | |
@height = height | |
@state = Array.new(@width) { Array.new(@height) { rand(2) } } | |
end | |
def is_alive(x, y, rel_x = 0, rel_y = 0) | |
cx = x + rel_x | |
cy = y + rel_y | |
if @wrapped | |
cx %= @width | |
cy %= @height | |
else | |
# return if out of range | |
return false if cx >= @width or cx < 0 or | |
cy >= @height or cy < 0 | |
end | |
state[cx][cy] == ALIVE | |
end | |
def count_neighbours(x, y) | |
neighbours = 0 | |
neighbours += 1 if is_alive(x, y, 1, 0) # East | |
neighbours += 1 if is_alive(x, y, 1, 1) # North East | |
neighbours += 1 if is_alive(x, y, 0, 1) # North | |
neighbours += 1 if is_alive(x, y, -1, 1) # North West | |
neighbours += 1 if is_alive(x, y, -1, 0) # West | |
neighbours += 1 if is_alive(x, y, -1, -1) # South West | |
neighbours += 1 if is_alive(x, y, 0, -1) # South | |
neighbours += 1 if is_alive(x, y, 1, -1) # South East | |
neighbours | |
end | |
def update_dimensions | |
width = @state.length | |
height = @state[0].length | |
# Find minimum height | |
1.upto(width - 1) do |x| | |
height = @state[x].length if height > @state[x].length | |
end | |
@width = width | |
@height = height | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment