Skip to content

Commit 2d4ce44

Browse files
committed
Revert "Optimize tile adjacency matching with pre-computed lookup tables"
This reverts commit 78c6230.
1 parent 43d1ff0 commit 2d4ce44

File tree

1 file changed

+23
-42
lines changed

1 file changed

+23
-42
lines changed

lib/wave_function_collapse/model.rb

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,11 @@ def initialize(tiles, width, height)
2323
@width = width.to_i
2424
@height = height.to_i
2525
@cells = []
26-
build_tile_adjacencies
2726
@height.times { |y| @width.times { |x| @cells << Cell.new(x, y, @tiles.shuffle) } }
2827
@uncollapsed_cells = @cells.reject(&:collapsed)
2928
@max_entropy = @tiles.length
3029
end
3130

32-
def build_tile_adjacencies
33-
# Pre-compute which tiles can be adjacent in each direction
34-
# This transforms the O(n²) runtime matching into O(1) lookup
35-
# We build a mapping from edge hash -> list of tiles with that edge in opposite direction
36-
@edge_to_tiles = {}
37-
38-
[:up, :right, :down, :left].each do |direction|
39-
@edge_to_tiles[direction] = {}
40-
41-
opposite_direction = OPPOSITE_OF[direction]
42-
43-
# For each tile, index it by its opposite edge
44-
@tiles.each do |tile|
45-
opposite_edge = case opposite_direction
46-
when :up then tile.up
47-
when :right then tile.right
48-
when :down then tile.down
49-
when :left then tile.left
50-
end
51-
52-
@edge_to_tiles[direction][opposite_edge] ||= []
53-
@edge_to_tiles[direction][opposite_edge] << tile
54-
end
55-
end
56-
end
57-
5831
def cell_at(x, y)
5932
@cells[@width * y + x]
6033
end
@@ -140,33 +113,41 @@ def evaluate_neighbor(source_cell, evaluation_direction)
140113
return if neighbor_cell.collapsed
141114

142115
original_tile_count = neighbor_cell.tiles.length
116+
opposite_direction = OPPOSITE_OF[evaluation_direction]
143117
neighbor_tiles = neighbor_cell.tiles
144118

145-
# Collect all valid adjacent tiles from all source tiles
146-
# Using pre-computed edge-to-tiles lookup with fast intersection via object_id
147-
valid_tile_ids = {}
148-
source_cell.tiles.each do |source_tile|
149-
# Get the edge of this source tile in the evaluation direction
150-
source_edge = case evaluation_direction
119+
source_tile_edges = source_cell.tiles.map do |source_tile|
120+
case evaluation_direction
151121
when :up then source_tile.up
152122
when :right then source_tile.right
153123
when :down then source_tile.down
154124
when :left then source_tile.left
155125
end
126+
end
156127

157-
# Look up all tiles that can be adjacent (pre-computed)
158-
compatible_tiles = @edge_to_tiles[evaluation_direction][source_edge]
159-
if compatible_tiles
160-
compatible_tiles.each do |tile|
161-
valid_tile_ids[tile.__id__] = tile
162-
end
128+
opposite_tile_edges = neighbor_tiles.map do |opposite_tile|
129+
case opposite_direction
130+
when :up then opposite_tile.up
131+
when :right then opposite_tile.right
132+
when :down then opposite_tile.down
133+
when :left then opposite_tile.left
163134
end
164135
end
165136

166-
# Keep only neighbor tiles that are in the valid set (O(n) intersection)
167137
new_tiles = []
168-
neighbor_tiles.each do |neighbor_tile|
169-
new_tiles << neighbor_tile if valid_tile_ids[neighbor_tile.__id__]
138+
ntc = neighbor_tiles.length
139+
i = 0
140+
while i < ntc
141+
ii = 0
142+
stel = source_tile_edges.length
143+
while ii < stel
144+
if source_tile_edges[ii] == opposite_tile_edges[i]
145+
new_tiles << neighbor_tiles[i]
146+
break
147+
end
148+
ii = ii.succ
149+
end
150+
i = i.succ
170151
end
171152

172153
neighbor_cell.tiles = new_tiles unless new_tiles.empty?

0 commit comments

Comments
 (0)