-
-
Save rkachowski/427880 to your computer and use it in GitHub Desktop.
| class GameOfLife < Chingu::GameState | |
| CELL_SIZE = 4 | |
| @@tick =0 | |
| def initialize | |
| super | |
| @grid = generate_grid | |
| self.input={:left_mouse_button=>:set_grid_block,:space=>:toggle_running, | |
| :right_mouse_button=>:unset_grid_block,:z=>:reset,:n=>:update_grid} | |
| @running = false | |
| end | |
| def update | |
| super | |
| update_grid if @running | |
| $window.caption = "conway generation #{@@tick}" | |
| end | |
| def draw | |
| super | |
| draw_grid | |
| draw_mouse | |
| end | |
| private | |
| def generate_grid | |
| width = $window.width/CELL_SIZE | |
| height = $window.height/CELL_SIZE | |
| grid = Array.new(width) | |
| col = Array.new(height) | |
| col.map!{false} | |
| grid.map!{Array.new(col)} | |
| grid | |
| end | |
| def draw_grid | |
| @grid.each_with_index do |a,x| | |
| a.each_with_index do |c,y| | |
| if c === true | |
| $window.fill_rect([x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE],0xff000000,0) | |
| end | |
| end | |
| end | |
| end | |
| def reset | |
| @grid = generate_grid | |
| @@tick =0 | |
| @running = false | |
| end | |
| def update_grid | |
| @new_grid = Marshal.load(Marshal.dump(@grid)) | |
| @grid.each_with_index do |a,x| | |
| a.each_with_index do |c,y| | |
| minus_x =x-1 | |
| minus_y = y-1 | |
| plus_x = x+1 | |
| plus_y = y+1 | |
| minus_x = @grid.length-1 if minus_x <0 | |
| minus_y = a.length-1 if minus_y <0 | |
| plus_y = 0 if plus_y >= a.length | |
| plus_x = 0 if plus_x >= @grid.length | |
| live_neighbours = 0 | |
| @grid[minus_x][y] == true ? live_neighbours+=1 : nil | |
| @grid[plus_x][y] == true ? live_neighbours+=1 : nil | |
| @grid[x][minus_y] == true ? live_neighbours+=1 : nil | |
| @grid[x][plus_y] == true ? live_neighbours+=1 : nil | |
| @grid[minus_x][plus_y] == true ? live_neighbours+=1 : nil | |
| @grid[plus_x][minus_y] == true ? live_neighbours+=1 : nil | |
| @grid[minus_x][minus_y] == true ? live_neighbours+=1 : nil | |
| @grid[plus_x][plus_y] == true ? live_neighbours+=1 : nil | |
| case live_neighbours | |
| when 0..1 then @new_grid[x][y] = false | |
| when 2 then @new_grid[x][y] = true if @new_grid[x][y] == true | |
| when 3 then @new_grid[x][y] = true | |
| when 4..8 then @new_grid[x][y] = false | |
| end | |
| end | |
| end | |
| @grid = @new_grid | |
| @@tick+=1 | |
| end | |
| def toggle_running | |
| @running = !@running | |
| end | |
| def set_grid_block | |
| x = ($window.mouse_x/CELL_SIZE).floor | |
| y = ($window.mouse_y/CELL_SIZE).floor | |
| @grid[x][y]=true | |
| end | |
| def unset_grid_block | |
| x = ($window.mouse_x/CELL_SIZE).floor | |
| y = ($window.mouse_y/CELL_SIZE).floor | |
| @grid[x][y]=false | |
| end | |
| def draw_mouse | |
| $window.fill_rect([($window.mouse_x/CELL_SIZE).floor*CELL_SIZE,($window.mouse_y/CELL_SIZE).floor*CELL_SIZE,CELL_SIZE,CELL_SIZE],0xaa0000ff,0) | |
| end | |
| end | |
| require 'chingu' | |
| require 'gosu' | |
| require_all(File.join(ROOT,"")) | |
| class Main < Chingu::Window | |
| def initialize | |
| super(640,480,false) | |
| self.input={:esc=>:exit} | |
| push_game_state(GameOfLife) | |
| end | |
| def draw | |
| super | |
| fill_rect([0,0,640,480], 0xffffffff, -2) | |
| end | |
| end | |
| Main.new.show |
sounds cool!
do you mean a spaceship? ( http://en.wikipedia.org/wiki/Spaceship_(cellular_automaton) ) or a glider? i could pretty easily add a class that contains various patterns / seeds - and insert them at the mouse cursor
Looking @ http://en.wikipedia.org/wiki/Conway's_Game_of_Life I realised I was thinking of a Glider. Heh, tons of various patterns that do odd stuff... a "Glider Gun" that produces gliders.
Commited to master - examples\game_of_life.rb
Hey I just invented a new pattern - The Toad Farm ... 4 pixels down, 1 to the left! :D
Hm, I'm wondering if the "wrap around" of cells mess up the game in your implementation. Wikipedia writes:
During this early research, Conway discovered that the F-pentomino (which he called the "R-pentomino") failed to stabilize in a small number of generations. In fact, it takes 1103 generations to stabilize, by which time it has a population of 116 and has fired six escaping gliders[9](in fact, these were the first gliders ever discovered).[10]
The pattern is this: http://upload.wikimedia.org/wikipedia/commons/1/1c/Game_of_life_fpento.svg
The thing is it doesn't behave like wikipedia says it should.. it doesn't settle down after 1103 generations.
Ah.. Markdown formatting, thank you.
damn markdown :P
i'm using the rectangular toroidal approach mentioned in the algorithms section on the wiki page, that might cause some inaccuracies. increasing the area should let it develop to a point it can stabilize (increase window size in main.rb from 640,480 and reduce CELL_SIZE in game_of_life.rb to < 4).
calling fill_rect a lot seems to cause a bottleneck one it hits a certain number of live cells, however
i think you are right. the pattern fires a few gilders which would wrap around and interfere with the pattern again. i'll add a "wrap" option later.
turns out it was wrong!
i edit the rules so it looks a bit clearer, and the f/r - pentomino should stabilise now
everything feels a lot more as I remember it now.. before your last tweak just about everything grew into a fullscreen mess-of-life.
added easier painting and with pre-defined patterns etc... glider, spaceship, acorn.
Ah, I remember this. Hey, this would be a cool thing to include in the Chingu-gem, is that OK with you?
Btw, do you know how to make a "walker"? A small combo of pixels that would walk across the screen, not getting bigger or smaller.