-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame_of_life.rb
138 lines (118 loc) · 3.66 KB
/
game_of_life.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
class Board
require 'pry'
MODIFIERS = ([-1,0,1].product([-1,0,1]- [[0,0]])).freeze
attr_accessor :board, :generation, :stats
def initialize(board=[])
@out = $stdout
@board = board
puts MODIFIERS if ENV['debug']
@board.map!{ |x,y| [x+10,y+20] }
@generation = 0
@stats = {}
end
# [x,y]
def find_neighbors_of(coordinate)
#@stats[:t_find_neighbors_of_start] = Time.now
MODIFIERS.map do |x,y|
[coordinate[0] + x, coordinate[1] + y]
end
#@stats[:t_find_neighbors_of_end] = Time.now
end
def find_living_neighbors(coordinate)
neighborhood = find_neighbors_of(coordinate)
(@board & neighborhood - [coordinate]).uniq
end
def count_living_neighbors(coordinate)
find_living_neighbors(coordinate).size
end
def print_board
screen_x, screen_y = get_window_width_and_height
output_string = ""
(screen_x-2).times do |i|
#output_string << ((i == 0 ) ? j.to_s : "X")
(screen_y-1).times do |j|
if board.include? [i,j]
#output_string << ((i == 0 && screen_y-5 == j) ? (j.to_s+"/n") : "")
output_string << ((i == 0 ) ? j.to_s : "X")
#print "X"
#output_string << "X"
else
#output_string << ((i == 0 && screen_y-5 == j) ? (j.to_s+"/n") : "")
output_string << (( j == 0 ) ? i.to_s : ".")
#print "."
end
#puts if j == (screen_y-2)
output_string << "\n" if j == (screen_y-2)
end
end
@generation += 1
@out.print output_string
#@out.print "Generation: " + @generation.to_s + (@stats[:t_find_neighbors_of_start] - @stats[:t_find_neighbors_of_start]).to_s + "\n"
@out.print "Generation: " + @generation.to_s + "\n"
@out.flush
# sleep 0.001
end
#Get terminal height and width (os x, ubuntu)
def get_window_width_and_height
`stty size`.scan(/\d+/).map { |s| s.to_i }
end
end
class Game
attr_accessor :b
def initialize
#setup = Struct.new(:name, :living_fields)
#setup.new("acron", [[3,5],[5,6],[3,6],[4,8],[5,9],[5,10],[5,11]])
#@b = Board.new([[3,5],[5,6],[3,6],[4,8],[5,9],[5,10],[5,11]]) #acron
# @b = Board.new([[5,5],[5,6],[4,6],[6,6], [4,7]]) #F-pentomino
#@b = Board.new([[5,5],[5,6],[4,5],[4,6], [4,10],[4,12],[6,11],[5,11]]) #die hard
#@b = Board.new([[5,5],[5,6],[5,7],[5,8],[4,8],[3,8],[2,7],[4,4],[2,4]]) #lightweight spaceship
#@b = Board.new([[3,3],[3,4],[3,5],[2,5],[1,4]]) #Glider
@b = Board.new([[3,3],[3,4],[3,5]]) #blinker
end
def play(times=100)
end
def find_all_fields_to_visit
@all_fields = []
@b.board.map do |x,y|
puts @b.find_neighbors_of([x,y]).inspect if @debug
@b.find_neighbors_of([x,y]).each do |element|
@all_fields << element
end
end
@all_fields.uniq.sort
end
def dead_fields
find_all_fields_to_visit - @b.board
end
def evolve_board
@next_gen = []
find_all_fields_to_visit.each do |field|
#puts "*** field " + field.to_s
if dead_fields.include? field then
@next_gen << field if ( @b.count_living_neighbors(field) == 3 )
#@b.board << field if ( @b.count_living_neighbors(field) == 3 )
else
if [0,1].include? (@b.count_living_neighbors(field))
#puts "it dies"
elsif [2,3].include? (@b.count_living_neighbors(field))
#puts "zjivej"
@next_gen << field
else (@b.count_living_neighbors(field)) > 3
#puts "it dies"
end
end
end
@b.board = @next_gen
@next_gen = []
end
end
g = Game.new
n = g.find_all_fields_to_visit
puts n.inspect
puts g.b.inspect
199.times {
g.b.print_board
#puts "#" * 88 + "\n"
g.evolve_board
#puts g.b.inspect
}