Skip to content

Commit 612c34c

Browse files
committed
Switch Model@grid to a 1d array, added Model#grid_cell for getting 2d cell position from 1d array, use an integer (1d grid index) instead of a string for Cell@neighbor key
1 parent eea1096 commit 612c34c

File tree

4 files changed

+33
-20
lines changed

4 files changed

+33
-20
lines changed

lib/wave_function_collapse/cell.rb

+9-8
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ def collapse
3333
self.tiles = [@tiles.max_by { |t| rand**(1.0 / t.probability) }]
3434
end
3535

36-
def neighbors(grid)
37-
return if grid.nil?
38-
39-
@neighbors["#{@x},#{@y}"] ||= begin
40-
up = grid[@x][@y + 1] if grid[@x] && @y < grid[0].length - 1
41-
down = grid[@x][@y - 1] if grid[@x] && @y.positive?
42-
right = grid[@x + 1][@y] if @x < grid.length - 1
43-
left = grid[@x - 1][@y] if @x.positive?
36+
def neighbors(model)
37+
return if model.nil?
38+
39+
@neighbors[model.width * y + x] ||= begin
40+
up = model.grid_cell(@x, @y + 1) if @y < model.height - 1
41+
down = model.grid_cell(@x, @y - 1) if @y.positive?
42+
right = model.grid_cell(@x + 1, @y) if @x < model.width - 1
43+
left = model.grid_cell(@x - 1, @y) if @x.positive?
44+
4445
{up: up, down: down, right: right, left: left}
4546
end
4647
end

lib/wave_function_collapse/model.rb

+22-10
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ def initialize(tiles, width, height)
2323
@width = width.to_i
2424
@height = height.to_i
2525

26-
@grid = Array.new(width) { |x| Array.new(height) { |y| Cell.new(x, y, @tiles.shuffle) } }
27-
@uncollapsed_cells_grid = @grid.flatten.reject(&:collapsed)
26+
# @grid = Array.new(width) { |x| Array.new(height) { |y| Cell.new(x, y, @tiles.shuffle) } }
27+
@grid = []
28+
@height.times { |y| @width.times { |x| @grid << Cell.new(x, y, @tiles.shuffle) } }
29+
@uncollapsed_cells_grid = @grid.reject(&:collapsed)
2830
@max_entropy = @tiles.length
2931
end
3032

33+
def grid_cell(x, y)
34+
@grid[@width * y + x]
35+
end
36+
3137
def complete?
3238
@uncollapsed_cells_grid.empty?
3339
end
@@ -53,6 +59,8 @@ def iterate
5359
end
5460

5561
def prepend_empty_row
62+
raise
63+
5664
x = 0
5765
while x < @width
5866
@grid[x].shift
@@ -79,18 +87,18 @@ def random_cell
7987
def generate_grid
8088
x = 0
8189
result = []
82-
lx = @grid.length
83-
while x < lx
90+
91+
while x < @width
8492
rx = result[x] = []
8593
y = 0
86-
pgx = @grid[x]
87-
ly = pgx.length
88-
while y < ly
89-
rx[y] = pgx[y].tile
94+
95+
while y < @height
96+
rx[y] = grid_cell(x, y).tile
9097
y += 1
9198
end
9299
x += 1
93100
end
101+
94102
result
95103
end
96104

@@ -110,7 +118,7 @@ def propagate(source_cell)
110118
end
111119

112120
def evaluate_neighbor(source_cell, evaluation_direction)
113-
neighbor_cell = source_cell.neighbors(@grid)[evaluation_direction]
121+
neighbor_cell = source_cell.neighbors(self)[evaluation_direction]
114122
return if neighbor_cell.nil? || neighbor_cell.collapsed
115123

116124
original_tile_count = neighbor_cell.tiles.length
@@ -122,23 +130,27 @@ def evaluate_neighbor(source_cell, evaluation_direction)
122130
neighbor_tiles = neighbor_cell.tiles
123131
sci = 0
124132
scil = source_tiles.length
133+
125134
while sci < scil
126135
source_tile = source_tiles[sci]
127136
sci += 1
128137
source_edge_hash = source_tile.send(evaluation_direction)
129138
nci = 0
130139
ncil = neighbor_tiles.length
140+
131141
while nci < ncil
132142
tile = neighbor_tiles[nci]
133143
nci += 1
134-
next if new_tile_ids.has_key?(tile.tileid)
144+
next if new_tile_ids[tile.tileid]
145+
135146
tile_edge_hash = tile.send(opposite_direction)
136147
if tile_edge_hash == source_edge_hash
137148
new_tile_ids[tile.tileid] = true
138149
new_tiles << tile
139150
end
140151
end
141152
end
153+
142154
neighbor_cell.tiles = new_tiles unless new_tiles.empty?
143155
@uncollapsed_cells_grid.delete(neighbor_cell) if neighbor_cell.collapsed
144156

lib/wave_function_collapse/window.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def draw_map
121121
column.reverse.each_with_index do |tile, y|
122122
inverted_y = (y - @model.height + 1).abs
123123

124-
entropy = @model.grid[x][inverted_y].entropy
124+
entropy = @model.grid_cell(x, inverted_y).entropy
125125

126126
if entropy > 1
127127
percent_entropy = (entropy.to_f / @model.max_entropy * 255).round

test/test_model.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def test_initialize
1313

1414
assert_equal 320, model.width
1515
assert_equal 240, model.height
16-
assert_equal 320 * 240, model.grid.map(&:size).sum
16+
assert_equal 320 * 240, model.grid.size
1717
assert_equal 3, model.max_entropy
1818
assert_equal 0, model.percent
1919
refute model.complete?

0 commit comments

Comments
 (0)