Continuing with my learning and experimentation with DRGTK, I wanted to implement a flood-fill algorithm on a canvas with some drawings.
This idea came from an old interview exercise I did some years ago.
The Flood Fill algorithm is commonly used in graphics software to fill an area with a specific color. It’s what powers the paint bucket tool.
So having a canvas and a pair of coordinates on that, the initial color is the one located in this location and the plan is to change it to another color, filling all adjacent pixels with the original color with the new one until a different one from the original one is reached.
My implementation is a recursive one:
def paint(x:, y:, base_color:, new_color:, sleep_time: 0)
return if new_color == base_color
coords_inside_matrix = y >= 0 && y < map.size && x >= 0 && x < map[0].size
pixel_should_be_painted = coords_inside_matrix && map[y][x] == base_color
return unless pixel_should_be_painted
map[y][x] = new_color # paint the cell
paint(x: x+1, y: y, base_color: base_color, new_color: new_color)
paint(x: x, y: y+1, base_color: base_color, new_color: new_color)
paint(x: x-1, y: y, base_color: base_color, new_color: new_color)
paint(x: x, y: y-1, base_color: base_color, new_color: new_color)
end
I worked on my solution using TDD, with Minitest spec tests, so it was easier to start with basic scenarios and also printed it while it moved the brush position recursively.
# Running:
paint(2-1)
changing x:2 y:1
[0, 0, 0, 0, 0]
[0, 0, 8, 0, 0]
[0, 0, 2, 3, 8]
[2, 2, 2, 0, 0]
[0, 0, 2, 0, 5]
paint(2-2)
changing x:2 y:2
[0, 0, 0, 0, 0]
[0, 0, 8, 0, 0]
[0, 0, 8, 3, 8]
[2, 2, 2, 0, 0]
[0, 0, 2, 0, 5]
paint(2-3)
changing x:2 y:3
[0, 0, 0, 0, 0]
[0, 0, 8, 0, 0]
[0, 0, 8, 3, 8]
[2, 2, 8, 0, 0]
[0, 0, 2, 0, 5]
paint(2-4)
changing x:2 y:4
[0, 0, 0, 0, 0]
[0, 0, 8, 0, 0]
[0, 0, 8, 3, 8]
[2, 2, 8, 0, 0]
[0, 0, 8, 0, 5]
On the Dragon Ruby side, I drew the matrix as a canvas and queried the mouse functions to get the cell position to paint or to change the color of the brush by clicking on a color palette box.
There is no pencil functionality so the canvas starts with a default drawing to play with it:
...and that's basically it. Not sure what will be next on this series. There is a game jam with Dragon Ruby starting soon, maybe I could participate on it :) .
Links to the app and code:
Happy hacking!
Top comments (1)
If you’re rendering a lot of solids, use the sprites output. It’s significantly faster because of texture caching.