Ruby game in life with Gosu - update not working

I am creating a Game of Life in Ruby using Gosu. My code is below. Right now, when I run "ruby gosu.rb", it opens a window with the correct dimensions and a pre-populated world, as it should be.

But as soon as I uncomment "@ game.tick!" in action updating the gosu file when I run "ruby gosu.rb" I get a black screen without a pre-populated world that I cannot close. Why is this and how to fix it?

Here you can find the github repository with the rest of the code. Any help is awesome.

Here is my game_of_life.rb

class Game attr_accessor :world def initialize(world=World.new, seeds=[]) @world = world seeds.each do |seed| world.cell_board[seed[0]][seed[1]].alive = true end end def tick! next_round_live_cells = [] next_round_dead_cells = [] world.cells.each do |cell| # Rule 1: # Any live cell with fewer than two live neighbours dies if cell.alive? && world.live_neighbours_around_cell(cell).count < 2 next_round_dead_cells << cell end # Rule 2: # Any live cell with two or three live neighbours lives on to the next generation if cell.alive? && world.live_neighbours_around_cell(cell).count == (2 || 3) next_round_live_cells << cell end # Rule 3: # Any live cell with more than three live neighbours dies if cell.alive? && world.live_neighbours_around_cell(cell).count > 3 next_round_dead_cells << cell end # Rule 4: # Any dead cell with exactly three live neighbours becomes a live cell if cell.dead? && world.live_neighbours_around_cell(cell).count == 3 next_round_live_cells << cell end end next_round_live_cells.each do |cell| cell.revive! end next_round_dead_cells.each do |cell| cell.die! end end end class World attr_accessor :rows, :cols, :cell_board, :cells # Scheme of default initialized world matrix #------------------------ # 0 1 2 # 0 [ dead, dead, dead ] # 1 [ dead, alive, dead ] # 2 [ dead, dead, dead ] #----------------------- def initialize(rows=3, cols=3) @rows = rows @cols = cols @cells = [] @cell_board = Array.new(rows) do |row| Array.new(cols) do |col| Cell.new(col, row) # note col is 1st, than is row end end cell_board.each do |row| row.each do |element| if element.is_a?(Cell) cells << element end end end end def live_cells cells.select { |cell| cell.alive } end def dead_cells cells.select { |cell| cell.alive == false } end def live_neighbours_around_cell(cell) live_neighbours = [] live_cells.each do |live_cell| # Neighbour to the North if live_cell.x == cell.x - 1 && live_cell.y == cell.y live_neighbours << live_cell end # Neighbour to the North-East if live_cell.x == cell.x - 1 && live_cell.y == cell.y + 1 live_neighbours << live_cell end # Neighbour to the East if live_cell.x == cell.x && live_cell.y == cell.y + 1 live_neighbours << live_cell end # Neighbour to the South-East if live_cell.x == cell.x + 1 && live_cell.y == cell.y + 1 live_neighbours << live_cell end # Neighbour to the South if live_cell.x == cell.x + 1 && live_cell.y == cell.y live_neighbours << live_cell end # Neighbour to the South-West if live_cell.x == cell.x + 1 && live_cell.y == cell.y - 1 live_neighbours << live_cell end # Neighbour to the West if live_cell.x == cell.x && live_cell.y == cell.y - 1 live_neighbours << live_cell end # Neighbour to the North-West if live_cell.x == cell.x - 1 && live_cell.y == cell.y - 1 live_neighbours << live_cell end end live_neighbours end def randomly_populate cells.each do |cell| cell.alive = [true, false].sample end end end class Cell attr_accessor :x, :y, :alive #, :height, :width def initialize(x=0, y=0) @x = x @y = y @alive = false # Gosu # @height = height # @width = width end def alive? alive end def dead? !alive end def die! @alive = false end def revive! @alive = true # same as > self.alive = true end end 

Here is my gosu code

 require 'gosu' require_relative 'gol.rb' class GameOfLifeWindow < Gosu::Window def initialize(height=800, width=600) # Basics @height = height @width = width super height, width, false, 500 self.caption = 'My Game of Life' # Colors @white = Gosu::Color.new(0xffededed) @black = Gosu::Color.new(0xff121212) # Game world @rows = height/10 @cols = width/10 world = World.new(@cols, @rows) @game = Game.new(world) @row_height = height/@rows @col_width = width/@cols @game.world.randomly_populate @generation = 0 end def update # unless @game.world.live_cells.count == 0 # @game.tick! @generation += 1 # end end def draw @game.world.cells.each do |cell| if cell.alive? draw_quad(cell.x * @col_width, cell.y * @row_height, @black, cell.x * @col_width + @col_width, cell.y * @row_height, @black, cell.x * @col_width + @col_width, cell.y * @row_height + @row_height, @black, cell.x * @col_width, cell.y * @row_height + @row_height, @black) end end end def button_down(id) case id when Gosu::KbSpace @game.world.randomly_populate when Gosu::KbEscape close end end def draw_background draw_quad(0, 0, @white, width, 0, @white, width, height, @white, 0, height, @white) end end window = GameOfLifeWindow.new window.show 
+4
source share
1 answer

Ok, now I know that the code is correct to execute the tick! cycle tick! only a lot is needed.

I made video tutorials on creating Game of Life in Ruby using TDD with the Rspec and Gosu game libraries, you can check them here> http://svenduplic.com/2013/03/25/conways-game-of-life-in -ruby.html

They contain the creation of the game from beginning to end, explaining to me every line. In the end, I will explain why the code here takes a long time to complete and optimize it properly.

+2
source

Source: https://habr.com/ru/post/1469390/


All Articles