Je crée Game of Life en Ruby en utilisant Gosu. Mon code est ci-dessous. Pour l'instant, lorsque j'exécute 'ruby gosu.rb', il ouvre la fenêtre avec les bonnes dimensions et le Monde pré-peuplé comme il se doit.
Mais dès que je dé-commente '@game.tick!' dans le fichier gosu file update action, en exécutant 'ruby gosu.rb', j'obtiens l'écran noir sans le Monde pré-peuplé que je ne peux pas fermer. Pourquoi est-ce que cela se produit et comment réparer cela ?
Vous pouvez trouver le dépôt GitHub avec le reste du code ici. Toute aide est appréciée.
Voici mon 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|
# Règle 1:
# Toute cellule vivante avec moins de deux voisins vivants meurt
if cell.alive? && world.live_neighbours_around_cell(cell).count < 2
next_round_dead_cells << cell
end
# Règle 2:
# Toute cellule vivante avec deux ou trois voisins vivants survit à la génération suivante
if cell.alive? && world.live_neighbours_around_cell(cell).count == (2 || 3)
next_round_live_cells << cell
end
# Règle 3:
# Toute cellule vivante avec plus de trois voisins vivants meurt
if cell.alive? && world.live_neighbours_around_cell(cell).count > 3
next_round_dead_cells << cell
end
# Règle 4:
# Toute cellule morte avec exactement trois voisins vivants devient une cellule vivante
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
# Schéma de matrice de monde initialisée par défaut
#------------------------
# 0 1 2
# 0 [ mort, mort, mort ]
# 1 [ mort, vivant, mort ]
# 2 [ mort, mort, mort ]
#-----------------------
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) # notez que col est en 1er, puis 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|
# Voisin au Nord
if live_cell.x == cell.x - 1 && live_cell.y == cell.y
live_neighbours << live_cell
end
# Voisin au Nord-Est
if live_cell.x == cell.x - 1 && live_cell.y == cell.y + 1
live_neighbours << live_cell
end
# Voisin à l'Est
if live_cell.x == cell.x && live_cell.y == cell.y + 1
live_neighbours << live_cell
end
# Voisin au Sud-Est
if live_cell.x == cell.x + 1 && live_cell.y == cell.y + 1
live_neighbours << live_cell
end
# Voisin au Sud
if live_cell.x == cell.x + 1 && live_cell.y == cell.y
live_neighbours << live_cell
end
# Voisin au Sud-Ouest
if live_cell.x == cell.x + 1 && live_cell.y == cell.y - 1
live_neighbours << live_cell
end
# Voisin à l'Ouest
if live_cell.x == cell.x && live_cell.y == cell.y - 1
live_neighbours << live_cell
end
# Voisin au Nord-Ouest
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
Voici mon code gosu
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