Looking for feedback on obvious logic errors on this, not optimizing. I keep getting weird tick counts on the end game message (ex: 1 tick turns into 11 ticks)
The largest error I can spot while running the code is on the 2nd tick, a very large amount of alive cells appear. I am too new to this to understand why, but it seems like the @alive_cells is not resetting back to 0 after each check.
Here is my entire code, its large but it should be child's play to anyone with experience.
class CellGame
def initialize
puts "How big do you want this game?"
@size = gets.chomp.to_i
@cell_grid = Array.new(@size) { Array.new(@size) }
@grid_storage = Array.new(@size) { Array.new(@size) }
@tick_count = 0
fill_grid_with_random_cells
end
def fill_grid_with_random_cells
@cell_grid.each do |row|
row.map! do |cell|
roll = rand(10)
if roll > 9
"•"
else
" "
end
end
end
check_cells_for_future_state
end
def check_for_any_alive_cells
@cell_grid.each do |row|
if row.include?("•")
check_cells_for_future_state
break
else
end_game_print_result
end
end
end
def check_cells_for_future_state
@cell_grid.each_with_index do |row, row_index|
row.each_with_index do |cell, cell_index|
@live_neighbors = 0
add_row_shift = (row_index + 1)
if add_row_shift == @size
add_row_shift = 0
end
add_cell_shift = (cell_index + 1)
if add_cell_shift == @size
add_cell_shift = 0
end
def does_this_include_alive(cell)
if cell.include?("•")
@live_neighbors +=1
end
end
top_left_cell = @cell_grid[(row_index - 1)][(cell_index - 1)]
does_this_include_alive(top_left_cell)
top_cell = @cell_grid[(row_index - 1)][(cell_index)]
does_this_include_alive(top_cell)
top_right_cell = @cell_grid[(row_index - 1)][(add_cell_shift)]
does_this_include_alive(top_right_cell)
right_cell = @cell_grid[(row_index)][(add_cell_shift)]
does_this_include_alive(right_cell)
bottom_right_cell = @cell_grid[(add_row_shift)][(add_cell_shift)]
does_this_include_alive(bottom_right_cell)
bottom_cell = @cell_grid[(add_row_shift)][(cell_index)]
does_this_include_alive(bottom_cell)
bottom_left_cell = @cell_grid[(add_row_shift)][(cell_index - 1)]
does_this_include_alive(bottom_left_cell)
left_cell = @cell_grid[(row_index)][(cell_index - 1)]
does_this_include_alive(left_cell)
if @live_neighbors == 2 || @live_neighbors == 3
@grid_storage[row_index][cell_index] = "•"
else
@grid_storage[row_index][cell_index] = " "
end
end
end
update_cell_grid
end
def update_cell_grid
@cell_grid = @grid_storage
print_cell_grid_and_counter
end
def print_cell_grid_and_counter
system"clear"
@cell_grid.each do |row|
row.each do |cell|
print cell + " "
end
print "\n"
end
@tick_count += 1
print "\n"
print "Days passed: #{@tick_count}"
sleep(0.25)
check_for_any_alive_cells
end
def end_game_print_result
print "#{@tick_count} ticks were played, end of game."
exit
end
end
I couldn't see where your code went wrong. It does have a recursive call which can easily cause strange behavior. Here is what I came up with:
class CellGame
def initialize(size)
@size = size; @archive = []
@grid = Array.new(size) { Array.new(size) { rand(3).zero? } }
end
def lives_on?(row, col)
neighborhood = (-1..1).map { |r| (-1..1).map { |c| @grid[row + r] && @grid[row + r][col + c] } }
its_alive = neighborhood[1].delete_at(1)
neighbors = neighborhood.flatten.count(true)
neighbors == 3 || neighbors == 2 && its_alive
end
def next_gen
(0...@size).map { |row| (0...@size).map { |col| lives_on?(row, col) } }
end
def play
tick = 0; incr = 1
loop do
@archive.include?(@grid) ? incr = 0 : @archive << @grid
sleep(0.5); system "clear"; @grid = next_gen
puts "tick - #{tick += incr}"
puts @grid.map { |row| row.map { |cell| cell ? '*' : ' ' }.inspect }
end
end
end
cg = CellGame.new 10
cg.play
The tick count stops but the program keeps running through the oscillator at the end.