2013-03-15 72 views
4

我在使用Gosu在Ruby中創建生命遊戲。我的代碼如下。現在,當我運行'ruby gosu.rb'時,它會打開窗口,並顯示適當的尺寸和預先填充的世界。與Gosu生活的Ruby遊戲 - 更新操作不起作用

但是,只要我取消註釋'@ game.tick!'在gosu文件更新操作中,在運行'ruby gosu.rb'時,我得到了沒有預先填充的世界的黑屏,我無法關閉它。爲什麼是這樣以及如何解決這個問題?

You can find github repo with rest of the code here.任何幫助都很棒。

這裏是我的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 

這裏是我的古藪代碼

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 
+1

當我從githup運行你的代碼時,gol會像我預期的那樣進行。也許發佈你的答案? – philosodad 2013-03-16 00:20:20

+0

我現在知道什麼是錯的。代碼中沒有什麼是錯誤的,但由於我的計算機很弱,因此遊戲需要花費很多時間才能加載,因爲它沒有優化......我會在這裏發佈優化代碼,當我做對了。 – oFca 2013-03-16 15:47:50

回答

2

好了,我現在的代碼是正確的認識,它只是需要很多循環通過tick!方法。

我做的視頻教程涵蓋使用TDD使用RSpec和古藪遊戲庫使生活的遊戲在Ruby中,你可以檢查出來這裏>http://svenduplic.com/2013/03/25/conways-game-of-life-in-ruby.html

它們包含從比賽一開始的製作結束,與我解釋每一行。最後,我解釋了爲什麼這裏的代碼需要很長時間才能正確完成並優化它。

+0

你不應該選擇你的答案嗎? ;)謝謝 - 你的教程vids非常棒 - 現在在惠普拉皮條上有足夠的動力i3 ... :) – 2016-10-01 05:37:24