nanolife 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/nanolife +4 -0
  3. data/lib/NanoLife.rb +193 -0
  4. metadata +66 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5b733078fbb180fe77d800bf342baa8e6114cb14
4
+ data.tar.gz: 0333ce746ca06539fb1b7c71cc8f807149472268
5
+ SHA512:
6
+ metadata.gz: a05382ec786a8e6fe9bf30bc307de23efcf80d1e386c265c4c2599f80836c133ab83e89871010ec984edc0da82ac2505e25ec734154af6c34b31d01a4c884726
7
+ data.tar.gz: bcc0c016b5c22cdc33fed832b4467eb256b65c19c02406f6421ccb2c8b60e00a7cbf33af2f573eaf21790d8d4fb6929e6609f0d2a200575dabe89d5c995b614f
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'NanoLife'
3
+ game = LifeGameWindow.new
4
+ game.show
@@ -0,0 +1,193 @@
1
+ #!/bin/env ruby
2
+ require 'rubygems'
3
+ require 'gosu'
4
+
5
+ WIN_WIDTH = 1024 # Window width
6
+ WIN_HEIGHT = 768 # Window height
7
+ CELL_SIZE = 8 # Size of cell square
8
+ CELL_COLOR = Gosu::Color.new(0xff00ffff)
9
+ EMPTY_COLOR = Gosu::Color.new(0x00000000)
10
+ MAX_FPS = 30 # For calculating max framerate
11
+
12
+ # Keybinds:
13
+ # s - Start and stop (pause) the game
14
+ # c - Clear the grid
15
+ # r - Randomize the grid
16
+ # Left Click - Invert the state of the cell clicked
17
+ # q/Esc - Quit
18
+
19
+ class LifeGameWindow < Gosu::Window
20
+ # Game of Life window/screen manager
21
+
22
+ # Initialize Gosu window and LifeGrid
23
+ def initialize
24
+ # Gosu window
25
+ super WIN_WIDTH, WIN_HEIGHT, false, 1000.0 / MAX_FPS
26
+ self.caption = 'NanoLife - Conway\'s Game of Life'
27
+ # Create a game of life grid and start randomly
28
+ @grid = LifeGrid.new(self)
29
+ @grid.randomize
30
+ # Set running to true. Game can be paused with keyboard
31
+ @running = true
32
+ end
33
+
34
+ # Turn on cursor
35
+ def needs_cursor?; true; end
36
+
37
+ # Update everything each frame before drawing
38
+ def update
39
+ if @running # and delta is met
40
+ @grid.update
41
+ end
42
+ end
43
+
44
+ # Draw screen
45
+ def draw
46
+ @grid.draw
47
+ end
48
+
49
+ # Override callback for a button pressed
50
+ def button_down(id)
51
+ if id == Gosu::KbEscape or id == Gosu::KbQ
52
+ close
53
+ elsif id == Gosu::KbS
54
+ @running = !@running
55
+ elsif id == Gosu::KbC
56
+ @grid.clear
57
+ elsif id == Gosu::KbR
58
+ @grid.randomize
59
+ elsif id == Gosu::MsLeft
60
+ @grid.invert_cell(
61
+ mouse_x.to_i / CELL_SIZE,
62
+ mouse_y.to_i / CELL_SIZE
63
+ )
64
+ end
65
+ end
66
+ end
67
+
68
+ class LifeGrid
69
+ # Manages the underlying array of cells and their life process
70
+
71
+ def initialize(window)
72
+ @num_cols = WIN_WIDTH / CELL_SIZE
73
+ @num_rows = WIN_HEIGHT / CELL_SIZE
74
+ @grid = create_grid
75
+ @window = window
76
+ end
77
+
78
+ # Create an empty grid array
79
+ def create_grid
80
+ return Array.new(@num_cols) {Array.new(@num_rows, 0)}
81
+ end
82
+
83
+ # Ipdate state of all cells based on Conway's Game of Life rules
84
+ def update
85
+ # For all cells check neighbors and kill or birth
86
+ tmp_grid = create_grid
87
+ (0...@num_cols).each do |x|
88
+ (0...@num_rows).each do |y|
89
+ num_neighbors = check_neighbors(x, y)
90
+
91
+ if num_neighbors < 2 and @grid[x][y] == 1
92
+ tmp_grid[x][y] = 0
93
+ end
94
+ if num_neighbors == 2 or num_neighbors == 3
95
+ if @grid[x][y] == 1
96
+ tmp_grid[x][y] = 1
97
+ end
98
+ end
99
+ if num_neighbors == 3 and @grid[x][y] == 0
100
+ tmp_grid[x][y] = 1
101
+ end
102
+ if num_neighbors > 3 and @grid[x][y] == 1
103
+ tmp_grid[x][y] = 0
104
+ end
105
+ end
106
+ end
107
+ @grid = tmp_grid
108
+ end
109
+
110
+ # Given an x and y, calculate how many neighbors cell has
111
+ def check_neighbors(x, y)
112
+ num_neighbors = 0
113
+
114
+ # Previous row
115
+ if y > 0 and x > 0
116
+ num_neighbors += @grid[x-1][y-1]
117
+ end
118
+ if y > 0
119
+ num_neighbors += @grid[x][y-1]
120
+ end
121
+ if x < @num_cols - 1 and y > 0
122
+ num_neighbors += @grid[x+1][y-1]
123
+ end
124
+
125
+ # Current row
126
+ if x > 0
127
+ num_neighbors += @grid[x-1][y]
128
+ end
129
+ if x < @num_cols - 1
130
+ num_neighbors += @grid[x+1][y]
131
+ end
132
+
133
+ # Lower row
134
+ if x > 0 and y < @num_rows - 1
135
+ num_neighbors += @grid[x-1][y+1]
136
+ end
137
+ if y < @num_rows - 1
138
+ num_neighbors += @grid[x][y+1]
139
+ end
140
+ if x < @num_cols - 1 and y < @num_rows - 1
141
+ num_neighbors += @grid[x+1][y+1]
142
+ end
143
+
144
+ return num_neighbors
145
+ end
146
+
147
+ # Draw the cell grid to the window
148
+ def draw
149
+ # draw grid
150
+ (0...@num_cols).each do |x|
151
+ (0...@num_rows).each do |y|
152
+ if @grid[x][y] == 0
153
+ color = EMPTY_COLOR
154
+ else
155
+ color = CELL_COLOR
156
+ end
157
+ realx = x * CELL_SIZE
158
+ realy = y * CELL_SIZE
159
+ @window.draw_quad(
160
+ realx, realy, color,
161
+ realx + CELL_SIZE, realy, color,
162
+ realx, realy + CELL_SIZE, color,
163
+ realx + CELL_SIZE, realy + CELL_SIZE, color,
164
+ )
165
+ end
166
+ end
167
+ end
168
+
169
+ # Flip the state of a cell. Useful for manual click manipulation
170
+ def invert_cell(x, y)
171
+ @grid[x][y] = (@grid[x][y] == 0 ? 1 : 0)
172
+ end
173
+
174
+ # Utility function to randomize grid
175
+ def randomize
176
+ (0...@num_cols).each do |x|
177
+ (0...@num_rows).each do |y|
178
+ @grid[x][y] = rand(2)
179
+ end
180
+ end
181
+ end
182
+
183
+ # Utility function to randomize grid
184
+ def clear
185
+ (0...@num_cols).each do |x|
186
+ (0...@num_rows).each do |y|
187
+ @grid[x][y] = 0
188
+ end
189
+ end
190
+ end
191
+
192
+ end
193
+
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nanolife
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - NanoDano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gosu
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.10.7
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.10'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.10.7
33
+ description: John Conway's Game of Life implemented using Gosu
34
+ email: nanodano@devdungeon.com
35
+ executables:
36
+ - nanolife
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - bin/nanolife
41
+ - lib/NanoLife.rb
42
+ homepage: https://github.com/DevDungeon/NanoLife
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.2.2
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: John Conway's Game of Life
66
+ test_files: []