寻找有关此明显逻辑错误的反馈,而不是优化。我一直在最终游戏消息上得到奇怪的滴答计数(例如:1滴答成11个滴答)
我在运行代码时发现的最大错误是在第二个刻度线上,出现了大量的活细胞。我太新了,不明白为什么,但似乎@alive_cells在每次检查后都没有重置为0。
这是我的整个代码,它很大,但它应该是任何有经验的人的孩子的游戏。
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
答案 0 :(得分:2)
我无法看到代码出错的地方。它确实有一个递归调用,很容易导致奇怪的行为。以下是我提出的建议:
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
滴答计数停止但程序在最后通过振荡器继续运行。
答案 1 :(得分:0)
我想重温这一点并自信地说我已经弄明白了!这是我的新解决方案 - 仍然是超级初学者专注。希望它可以帮助别人。
class Game
# Uses constants for values that won't change
LIVE = ""
DEAD = " "
WIDTH = 68
HEIGHT = 34
def initialize
# Sets our grid to a new empty grid (set by method below)
@grid = empty_grid
# Randomly fills our grid with live cells
@grid.each do |row|
# Map will construct our new array, we use map! to edit the @grid
row.map! do |cell|
if rand(10) == 1
LIVE # Place a live cell
else
DEAD # Place a dead cell
end
end
end
# Single line implimentation
# @grid.each {|row|row.map! {|cell|rand(10) == 1 ? LIVE : DEAD}}
loop_cells #start the cycle
end
def empty_grid
Array.new(HEIGHT) do
# Creates an array with HEIGHT number of empty arrays
Array.new(WIDTH) do
# Fills each array with a dead cell WIDTH number of times
DEAD
end
end
# Single line implimentation
# Array.new(HEIGHT){ Array.new(WIDTH) { DEAD } }
end
def print_grid # Prints our grid to the terminal
system "clear" # Clears the terminal window
# Joins cells in each row with an empty space
rows = @grid.map do |row|
row.join(" ")
end
# Print rows joined by a new line
print rows.join("\n")
# Single line implimentation
# print @grid.map{|row| row.join(" ")}.join("\n")
end
def loop_cells
print_grid # Start by printing the current grid
new_grid = empty_grid # Set an empty grid (this will be the next life cycle)
# Loop through every cell in every row
@grid.each_with_index do |row, row_index|
row.each_with_index do |cell, cell_index|
# Find the cells friends
friends = find_friends(row_index, cell_index)
# Apply life or death rules
if cell == LIVE
state = friends.size.between?(2,3)
else
state = friends.size == 3
end
# Set cell in new_grid for the next cycle
new_grid[row_index][cell_index] = state ? LIVE : DEAD
end
end
# Replace grid and start over
@grid = new_grid
start_over
end
def find_friends(row_index, cell_index)
# Ruby can reach backwards through arrays and start over at the end - but it cannot reach forwards. If we're going off the grid, start over at 0
row_fix = true if (row_index + 1) == HEIGHT
cell_fix = true if (cell_index + 1) == WIDTH
# You'll see below I will use 0 if one of these values is truthy when checking cells to the upper right, right, lower right, lower, and lower left.
# Check each neighbor, use 0 if we're reaching too far
friends = [
@grid[(row_index - 1)][(cell_index - 1)],
@grid[(row_index - 1)][(cell_index)],
@grid[(row_index - 1)][(cell_fix ? 0 : cell_index + 1)],
@grid[(row_index)][(cell_fix ? 0 : cell_index + 1)],
@grid[(row_fix ? 0 : row_index + 1)][(cell_fix ? 0 : cell_index + 1)],
@grid[(row_fix ? 0 : row_index + 1)][(cell_index)],
@grid[(row_fix ? 0 : row_index + 1)][(cell_index - 1)],
@grid[(row_index)][(cell_index - 1)]
]
# Maps live neighbors into an array, removes nil values
friends.map{|x| x if x == LIVE}.compact
end
def start_over
sleep 0.1
loop_cells
end
end
# Start game when file is run
Game.new