- dsf = state->clues->tmpdsf;
- dsf_init(dsf, W*h + w*H);
- /* Start by identifying all the outer edges with each other. */
- for (y = 0; y < h; y++) {
- dsf_merge(dsf, 0, y*W+0);
- dsf_merge(dsf, 0, y*W+w);
- }
- for (x = 0; x < w; x++) {
- dsf_merge(dsf, 0, W*h + 0*w+x);
- dsf_merge(dsf, 0, W*h + h*w+x);
- }
- /* Now go through the actual grid. */
- for (y = 0; y < h; y++)
- for (x = 0; x < w; x++) {
- if (state->soln[y*w+x] >= 0) {
- /*
- * There isn't a \ in this square, so we can unify
- * the top edge with the left, and the bottom with
- * the right.
- */
- dsf_merge(dsf, y*W+x, W*h + y*w+x);
- dsf_merge(dsf, y*W+(x+1), W*h + (y+1)*w+x);
- }
- if (state->soln[y*w+x] <= 0) {
- /*
- * There isn't a / in this square, so we can unify
- * the top edge with the right, and the bottom
- * with the left.
- */
- dsf_merge(dsf, y*W+x, W*h + (y+1)*w+x);
- dsf_merge(dsf, y*W+(x+1), W*h + y*w+x);
- }
- }
- /* Now go through again and mark the appropriate edges as erroneous. */
- for (y = 0; y < h; y++)
- for (x = 0; x < w; x++) {
- int erroneous = 0;
- if (state->soln[y*w+x] > 0) {
- /*
- * A / separates the top and left edges (which
- * must already have been identified with each
- * other) from the bottom and right (likewise).
- * Hence it is erroneous if and only if the top
- * and right edges are nonequivalent.
- */
- erroneous = (dsf_canonify(dsf, y*W+(x+1)) !=
- dsf_canonify(dsf, W*h + y*w+x));
- } else if (state->soln[y*w+x] < 0) {
- /*
- * A \ separates the top and right edges (which
- * must already have been identified with each
- * other) from the bottom and left (likewise).
- * Hence it is erroneous if and only if the top
- * and left edges are nonequivalent.
- */
- erroneous = (dsf_canonify(dsf, y*W+x) !=
- dsf_canonify(dsf, W*h + y*w+x));
- }
- if (erroneous) {
- state->errors[y*W+x] |= ERR_SQUARE;
- err = TRUE;
+ {
+ struct findloopstate *fls = findloop_new_state(W*H);
+ struct slant_neighbour_ctx ctx;
+ ctx.state = state;
+
+ if (findloop_run(fls, W*H, slant_neighbour, &ctx))
+ err = TRUE;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ int u, v;
+ if (state->soln[y*w+x] == 0) {
+ continue;
+ } else if (state->soln[y*w+x] > 0) {
+ u = y*W+(x+1);
+ v = (y+1)*W+x;
+ } else {
+ u = (y+1)*W+(x+1);
+ v = y*W+x;
+ }
+ if (findloop_is_loop_edge(fls, u, v))
+ state->errors[y*W+x] |= ERR_SQUARE;