Flood fill means that it takes initial rectangular area containing land and water cells and imitates flooding it: each flood step water cell converts neighbour land cells (up, left, right and down) to water.
It takes some steps to completely flood an area and after that algorithm stops. We must implement FloodFill in recursive manner and make flood method call itself until all the area becomes water.
But something goes wrong. What is my problem?
class RecursiveFloodFill implements FloodFill {
private char[][] grid;
@Override
public void flood(final String map, final FloodLogger logger) {
logger.log(map);
String newMap = floodStep(map);
if (!newMap.equals(map)) {
flood(newMap, logger);
}
}
private String floodStep(final String map) {
char[][] area = stringToArea(map);
char[][] newArea = new char[area.length][area[0].length];
for (int row = 0; row < area.length; row++) {
System.arraycopy(area[row], 0, newArea[row], 0, area[row].length);
}
for (int row = 0; row < area.length; row++) {
for (int col = 0; col < area[row].length; col++) {
if (area[row][col] == WATER) {
newArea[row - 1][col] = WATER;
newArea[row + 1][col] = WATER;
newArea[row][col - 1] = WATER;
newArea[row][col + 1] = WATER;
}
}
}
}
return areaToString(newArea);
}
The algorithm cannot just scan and change the array in one pass!
Negative example, how it does not work!
Just one row (one-dimensional) and using
WandLinstead of░and█. Lets start withWLLLand work left to right:0is Water → nothing done:WLLL1is Land and has neighbor Water → changed to Water:WWLL2is Land and (now) has neighbor Water → changed to Water:WWWL3same as above:WWWWat the end of one iteration the whole row is Water.
This will not happen if working right to left:
3is Land but no Water neighbor → nothing changed:WLLL2is Land but no Water neighbor → nothing changed:WLLL1is Land with Water neighbor → changed to Water:WWLL0is Water → nothing changed:WWLLnow only only Land was changed to Water.
Similar will also happen with subsequent rows, two-dimensional map.
Some suggestions:
Pseudocode first option, using a boolean array to hold the values to be changed:
obviously using correct dimensions, indices, methods, ...
This is a single iteration, it must be repeated until the map is not further changed.
Pseudocode second option, using a third value in map, to denote the values to be changed:
Note:
nearWatershould not consider SWAMP as being WATER!obviously using correct dimensions, indices, methods, ...
This is a single iteration, it must be repeated until the map is not further changed.
This is not the algorithm called Flood Fill!
The Flood Fill algorithm usually starts at a single position and floods its neighbors recursively - it usually does not scan the whole map.