Module: TinyFill
- Defined in:
- lib/tiny_fill.rb
Overview
TinyFill is a module that implements a flood fill algorithm. It’s useful in games for detecting enclosed areas within a 2D map.
usage:
map = [
[false, false, true, false, false],
[false, false, true, false, false],
[false, false, true, false, false],
[true, true, true, false, false],
[false, false, false, false, false],
]
# fill any enclosed area starting at [1, 1], max search of 10 cells
TinyFill.fill!(
map: map,
start_x: 1,
start_y: 1,
max_search: 10
)
=> [
[true, true, true, false, false],
[true, true, true, false, false],
[true, true, true, false, false],
[true, true, true, false, false],
[false, false, false, false, false],
]
Class Method Summary collapse
Class Method Details
.fill!(map:, start_x:, start_y:, max_search:) ⇒ Object
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 |
# File 'lib/tiny_fill.rb', line 34 def self.fill!(map:, start_x:, start_y:, max_search:) wid = map.first.length hgt = map.length return nil unless start_x >= 0 return nil unless start_y >= 0 return nil unless start_x < wid return nil unless start_y < hgt return nil if max_search <= 0 return nil if map[start_y][start_x] # starting point is already on a border search_queue = [[start_x, start_y]] map[start_y][start_x] = true cells_checked = 1 loop do break nil if cells_checked > max_search break map if search_queue.length == 0 cx, cy = search_queue.shift [ [cx , cy - 1], [cx + 1, cy - 1], [cx + 1, cy ], [cx + 1, cy + 1], [cx , cy + 1], [cx - 1, cy + 1], [cx - 1, cy ], [cx - 1, cy - 1], ].each do |next_cell| nx, ny = next_cell next if nx < 0 next if ny < 0 next if nx >= wid next if ny >= hgt next if map[ny][nx] map[ny][nx] = true cells_checked += 1 search_queue << [nx, ny] end end end |