Class: LifeCalculator
- Inherits:
-
Object
- Object
- LifeCalculator
- Defined in:
- lib/life_game_viewer/model/life_calculator.rb
Overview
Performs calculations relating to determination of a cell’s neighbors and the next generation. Generally, ‘next_generation’ will be the only method that will need to be called, but the others are provided publicly, since the Game of Life is all about experimentation.
See Wikipedia for more information about Conway’s Game of Life.
Rules distilled:
1) Any live cell with fewer than two live neighbours dies, as if caused by under-population. 2) Any live cell with two or three live neighbours lives on to the next generation. 3) Any live cell with more than three live neighbours dies, as if by overcrowding. 4) Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
Instance Method Summary collapse
- #dead_cell_should_become_alive(model, row, col) ⇒ Object
- #live_cell_should_continue_to_live(model, row, col) ⇒ Object
-
#neighbors(model, row, col) ⇒ Object
Returns an array of [row, col] tuples corresponding to the cells neighboring the specified cell location.
-
#next_generation(old_model) ⇒ Object
Returns a new model with the next generation’s data.
-
#num_living_neighbors(model, row, col) ⇒ Object
Returns an array of [row, col] tuples corresponding to those neighbor cells that are alive.
-
#should_live(model, row, col) ⇒ Object
Returns whether or not (as true or false) the specified cell should continue to live in the next generation.
Instance Method Details
#dead_cell_should_become_alive(model, row, col) ⇒ Object
99 100 101 |
# File 'lib/life_game_viewer/model/life_calculator.rb', line 99 def dead_cell_should_become_alive(model, row, col) num_living_neighbors(model, row, col) == 3 end |
#live_cell_should_continue_to_live(model, row, col) ⇒ Object
95 96 97 |
# File 'lib/life_game_viewer/model/life_calculator.rb', line 95 def live_cell_should_continue_to_live(model, row, col) (2..3).include?(num_living_neighbors(model, row, col)) end |
#neighbors(model, row, col) ⇒ Object
Returns an array of [row, col] tuples corresponding to the cells neighboring the specified cell location. “Neighbor” is defined as a cell with up/down/left/right/diagonal adjacency to the specified cell.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/life_game_viewer/model/life_calculator.rb', line 27 def neighbors(model, row, col) neighbors = [] at_left_edge = col == 0 at_right_edge = col == model.column_count - 1 at_top_edge = row == 0 at_bottom_edge = row == model.row_count - 1 col_to_left = col - 1 col_to_right = col + 1 row_above = row - 1 row_below = row + 1 # In its own row, return the cell to the left and right as possible. unless at_left_edge neighbors << [row, col_to_left] end unless at_right_edge neighbors << [row, col_to_right] end # Process the row above unless at_top_edge unless at_left_edge neighbors << [row_above, col_to_left] end neighbors << [row_above, col] unless at_right_edge neighbors << [row_above, col_to_right] end end # Process the row below unless at_bottom_edge unless at_left_edge neighbors << [row_below, col_to_left] end neighbors << [row_below, col] unless at_right_edge neighbors << [row_below, col_to_right] end end neighbors end |
#next_generation(old_model) ⇒ Object
Returns a new model with the next generation’s data.
18 19 20 21 22 |
# File 'lib/life_game_viewer/model/life_calculator.rb', line 18 def next_generation(old_model) old_model.class.send(:create, old_model.row_count, old_model.column_count) do |row, col| should_live(old_model, row, col) end end |
#num_living_neighbors(model, row, col) ⇒ Object
Returns an array of [row, col] tuples corresponding to those neighbor cells that are alive.
78 79 80 81 82 83 84 |
# File 'lib/life_game_viewer/model/life_calculator.rb', line 78 def num_living_neighbors(model, row, col) neighbors(model, row, col).inject(0) do |num_living, neighbor| neighbor_row, neighbor_column = neighbor num_living += 1 if model.alive?(neighbor_row, neighbor_column) num_living end end |
#should_live(model, row, col) ⇒ Object
Returns whether or not (as true or false) the specified cell should continue to live in the next generation.
89 90 91 92 93 |
# File 'lib/life_game_viewer/model/life_calculator.rb', line 89 def should_live(model, row, col) model.alive?(row, col) \ ? live_cell_should_continue_to_live(model, row, col) \ : dead_cell_should_become_alive(model, row, col) end |