I think I have an algorithm that will do what you need.
The first step is finding all the starting points (which is easy enough), initialise a path with the point you're at, and then attempt to follow a route either left, right, up or down from that point.
public void start() {
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (array[y][x] == 0) {
int pos[] = {x,y};
path = new ArrayList<int[]>();
path.add(pos);
startx = x;
starty = y;
follow(x, y, 1, 0);
follow(x, y, -1, 0);
follow(x, y, 0, 1);
follow(x, y, 0, -1);
}
}
}
}
Once you start following a route in a particular direction, if you've reached your start point again, you've found a cycle, so you can't output the path you took to get there and abandon any further search along this route.
If you find a non-empty cell, you need to add your current position to your path history, and then attempt to recursively follow another route at right angles to the direction you are on. So if you're going left or right, you now try only up or down, and vice versa.
If your route takes you past an edge without finding either your start point or a non-empty cell, you obviously can go no further.
private void follow(int x, int y, int dx, int dy) {
x += dx;
y += dy;
while (x >= 0 && x < w && y >= 0 && y < h) {
if (x == startx && y == starty) {
for (int[] pos : path) {
System.out.printf("[%d,%d] ",pos[1], pos[0]);
}
System.out.printf("\n");
break;
}
if (array[y][x] != 0) {
int pos[] = {x,y};
path.add(pos);
if (dx != 0) {
follow(x, y, 0, 1);
follow(x, y, 0, -1);
}
else {
follow(x, y, 1, 0);
follow(x, y, -1, 0);
}
path.remove(path.size()-1);
}
x += dx;
y += dy;
}
}
Here's a full working example on ideone
I've noticed a couple of issues with this algorithm that may not be ideal for you depending on your requirements.
- You actually get two versions of each path - one following a clockwise route and the other obviously counter-clockwise.
- Some of the paths cross over their own route. For example, something like a figure of eight pattern. I don't know whether that is something you would be accept as a valid cycle or not.