1- require "set"
2-
31module WaveFunctionCollapse
42 class Model
53 MAX_ITERATIONS = 5_000
@@ -27,7 +25,7 @@ def initialize(tiles, width, height)
2725 @cells = [ ]
2826 build_tile_adjacencies
2927 @height . times { |y | @width . times { |x | @cells << Cell . new ( x , y , @tiles . shuffle ) } }
30- @uncollapsed_cells = Set . new ( @cells . reject ( &:collapsed ) )
28+ @uncollapsed_cells = @cells . reject ( &:collapsed )
3129 @max_entropy = @tiles . length
3230 end
3331
@@ -66,7 +64,7 @@ def complete?
6664 end
6765
6866 def percent
69- ( ( @width * @height ) - @uncollapsed_cells . size . to_f ) / ( @width * @height ) * 100
67+ ( ( @width * @height ) - @uncollapsed_cells . length . to_f ) / ( @width * @height ) * 100
7068 end
7169
7270 def solve
@@ -92,7 +90,7 @@ def prepend_empty_row
9290 while x < @width
9391 new_cell = Cell . new ( x , @height - 1 , @tiles )
9492 @cells << new_cell
95- @uncollapsed_cells . add ( new_cell )
93+ @uncollapsed_cells << new_cell
9694 x = x . succ
9795 end
9896 @width . times { |x |
@@ -101,7 +99,7 @@ def prepend_empty_row
10199 end
102100
103101 def random_cell
104- @uncollapsed_cells . to_a . sample
102+ @uncollapsed_cells . sample
105103 end
106104
107105 def generate_grid
@@ -179,24 +177,27 @@ def evaluate_neighbor(source_cell, evaluation_direction)
179177 end
180178
181179 def find_lowest_entropy
182- return nil if @uncollapsed_cells . empty?
183-
184- min_e = nil
180+ ucg = @uncollapsed_cells
181+ i = 0
182+ l = ucg . length
183+ min_e = ucg [ 0 ] . entropy
185184 acc = [ ]
185+ while i < l
186+ cc = ucg [ i ]
187+ next i = i . succ if !cc
186188
187- @uncollapsed_cells . each do |cell |
188- ce = cell . entropy
189-
190- if min_e . nil? || ce < min_e
189+ ce = cc . entropy
190+ if ce < min_e
191191 min_e = ce
192192 acc . clear
193- acc << cell
193+ acc << i
194194 elsif ce == min_e
195- acc << cell
195+ acc << i
196196 end
197- end
198197
199- acc . sample
198+ i = i . succ
199+ end
200+ ucg [ acc . sample ]
200201 end
201202 end
202203end
0 commit comments