ref: 0589681d9dca09548023ddbd0b8eab5be21d8ce8
parent: 5fb108db00c8ad50b838274c24f7d1afc2cdd19b
author: Simon Tatham <anakin@pobox.com>
date: Mon Mar 26 06:20:51 EDT 2007
Stop failing assertions when we encounter an insoluble puzzle. [originally from svn r7408]
--- a/rect.c
+++ b/rect.c
@@ -329,6 +329,11 @@
number->npoints--;
}
+/*
+ * Returns 0 for failure to solve due to inconsistency; 1 for
+ * success; 2 for failure to complete a solution due to either
+ * ambiguity or it being too difficult.
+ */
static int rect_solver(int w, int h, int nrects, struct numberdata *numbers,
unsigned char *hedge, unsigned char *vedge,
random_state *rs)
@@ -434,6 +439,14 @@
* Indexing of this array is by the formula
*
* overlaps[(rectindex * h + y) * w + x]
+ *
+ * A positive or zero value indicates what it sounds as if it
+ * should; -1 indicates that this square _cannot_ be part of
+ * this rectangle; and -2 indicates that it _definitely_ is
+ * (which is distinct from 1, because one might very well know
+ * that _if_ square S is part of rectangle R then it must be
+ * because R is placed in a certain position without knowing
+ * that it definitely _is_).
*/
overlaps = snewn(nrects * w * h, int);
memset(overlaps, 0, nrects * w * h * sizeof(int));
@@ -526,7 +539,10 @@
if (overlaps[(i * h + y) * w + x] >= -1) {
int j;
- assert(overlaps[(i * h + y) * w + x] > 0);
+ if (overlaps[(i * h + y) * w + x] <= 0) {
+ ret = 0; /* inconsistency */
+ goto cleanup;
+ }
#ifdef SOLVER_DIAGNOSTICS
printf("marking %d,%d as known for rect %d"
" (sole remaining number position)\n", x, y, i);
@@ -568,7 +584,10 @@
for (yy = miny; yy < maxy; yy++)
for (xx = minx; xx < maxx; xx++)
if (overlaps[(i * h + yy) * w + xx] >= -1) {
- assert(overlaps[(i * h + yy) * w + xx] > 0);
+ if (overlaps[(i * h + yy) * w + xx] <= 0) {
+ ret = 0; /* inconsistency */
+ goto cleanup;
+ }
#ifdef SOLVER_DIAGNOSTICS
printf("marking %d,%d as known for rect %d"
" (intersection of all placements)\n",
@@ -847,15 +866,17 @@
}
}
- ret = TRUE;
+ cleanup:
+ ret = 1;
for (i = 0; i < nrects; i++) {
#ifdef SOLVER_DIAGNOSTICS
printf("rect %d has %d possible placements\n",
i, rectpositions[i].n);
#endif
- assert(rectpositions[i].n > 0);
- if (rectpositions[i].n > 1) {
- ret = FALSE;
+ if (rectpositions[i].n <= 0) {
+ ret = 0; /* inconsistency */
+ } else if (rectpositions[i].n > 1) {
+ ret = 2; /* remaining uncertainty */
} else if (hedge && vedge) {
/*
* Place the rectangle in its only possible position.
@@ -1639,9 +1660,9 @@
ret = rect_solver(params->w, params->h, nnumbers, nd,
NULL, NULL, rs);
else
- ret = TRUE; /* allow any number placement at all */
+ ret = 1; /* allow any number placement at all */
- if (ret) {
+ if (ret == 1) {
/*
* Now place the numbers according to the solver's
* recommendations.