You can do this with a recursive method using the FloodFill theory.
Basically, go through your grid and each time you find X, replace it with Z, as well as 4 neighboring ones (if applicable). But the trick is this: instead of just replacing them and looping around each time, call the same (calling) method again to do this. Recursiveness does the rest.
Here is his (quick-made) pseudo-code version: (assuming your grid is indexed from 0 to xmax, from 0 to ymax)
int numberOfBubbles = 0; for (x = 0 to xmax) { for (y = 0 to ymax) { if (getCharAt(x, y) == "X") { // this if is needed because you want to count the bubbles. If not, you could just do handleBubble(x, y); numberOfBubbles++; handleBubble(x, y); } } } // Recursive method void handleBubble(int x, int y) { if (getCharAt(x, y) != "X") { return; // exit condition } getCharAt(x, y) = "Z"; if (x > 0) handleBubble(x-1, y); if (x < xmax) handleBubble(x+1, y); if (y > 0) handleBubble(x, y-1); if (y < ymax) handleBubble(x, y+1); }
As far as I know, this is a solution only for this problem, which works no matter what strange shape your bubble is. The difficulty is also good.
This can be optimized further since it is currently checking for characters that obviously do not contain X (since they have just been replaced with Z). This remains as an exercise for the reader :)
(Note: the minesweeper game, among other things, is based on this decision)
Guillaume
source share