I'm trying to use a flood fill algorithm to count the number of "rooms" in a 2d grid. I have the algorithm already which is:
import sys
im = [list('...##########....................................'),
list('...#........#....####..................##########'),
list('...#........#....#..#...############...#........#'),
list('...##########....#..#...#..........#...##.......#'),
list('.......#....#....####...#..........#....##......#'),
list('.......#....#....#......############.....##.....#'),
list('.......######....#........................##....#'),
list('.................####........####..........######')]
HEIGHT = len(im)
WIDTH = len(im[0])
def floodFill(image,x,y,newChar, oldChar = None):
if oldChar == None:
oldChar = image[y][x]
if oldChar == newChar or image[y][x] != oldChar:
return
image[y][x] = newChar
if y + 1 < HEIGHT and image[y + 1][x] == oldChar:
floodFill(image, x, y + 1, newChar, oldChar)
if y - 1 >= 0 and image[y - 1][x] == oldChar:
floodFill(image, x, y - 1, newChar, oldChar)
if x + 1 < WIDTH and image[y][x + 1] == oldChar:
floodFill(image, x + 1, y, newChar, oldChar)
if x - 1 >= 0 and image[y][x - 1] == oldChar:
floodFill(image, x - 1, y, newChar, oldChar)
return
def printImage(image):
for y in range(HEIGHT):
for x in range(WIDTH):
sys.stdout.write(image[y][x])
sys.stdout.write('\n')
sys.stdout.write('\n')
What I'm trying to do is use a nested for
loop to find the periods and run the algorithm, but I'm not sure how to successfully adjust the x and y coordinates as I run through the list. So far what I have is:
def loops(image):
count = 0
for i in image:
for j in i:
if j == '.':
count += 1
x =
y =
floodFill(image,x,y,'?',oldChar=None)
My question is, how do I find the x
and y
coordinate of the periods to place into my function?
You could use Python's built-in enumerate()
function to determine the needed indices easily. You didn't ask, but I also suggest that you use its print()
function to output the image instead of writing directly to sys.stdout
. In addition to that, the whole function could be simplified by outputting a whole row at a time.
Here's your code with those modifications (along with some other formatting changes I made to make it more readable). Note that I don't think your loops()
function is identifying the "rooms" correctly, but also don't think that was what you asked about.
img = [list('...##########....................................'),
list('...#........#....####..................##########'),
list('...#........#....#..#...############...#........#'),
list('...##########....#..#...#..........#...##.......#'),
list('.......#....#....####...#..........#....##......#'),
list('.......#....#....#......############.....##.....#'),
list('.......######....#........................##....#'),
list('.................####........####..........######')]
HEIGHT = len(img)
WIDTH = len(img[0])
def floodFill(image, x, y, newChar, oldChar=None):
if oldChar == None:
oldChar = image[y][x]
if oldChar == newChar or image[y][x] != oldChar:
return
image[y][x] = newChar
if y+1 < HEIGHT and image[y+1][x] == oldChar:
floodFill(image, x, y+1, newChar, oldChar)
if y-1 >= 0 and image[y-1][x] == oldChar:
floodFill(image, x, y-1, newChar, oldChar)
if x+1 < WIDTH and image[y][x+1] == oldChar:
floodFill(image, x+1, y, newChar, oldChar)
if x-1 >= 0 and image[y][x-1] == oldChar:
floodFill(image, x-1, y, newChar, oldChar)
return
def printImage(image):
# for y in range(HEIGHT):
# for x in range(WIDTH):
# print(image[y][x], end='')
# print()
# print()
for row in image:
print(''.join(row))
def loops(image):
count = 0
for y, i in enumerate(image):
for x, j in enumerate(i):
if j == '.':
count += 1
floodFill(image, x, y, '?', oldChar=None)
loops(img)
printImage(img)
Results:
???##########????????????????????????????????????
???#????????#????####??????????????????##########
???#????????#????#??#???############???#????????#
???##########????#??#???#??????????#???##???????#
???????#????#????####???#??????????#????##??????#
???????#????#????#??????############?????##?????#
???????######????#????????????????????????##????#
?????????????????####????????####??????????######