Doc tweaks for Solo.
[sgt/puzzles] / pattern.c
index 91b1a2f..4fc1562 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -281,6 +281,15 @@ static void generate(random_state *rs, int w, int h, unsigned char *retgrid)
                     for (q = -1; q <= +1; q++) {
                         if (i+p < 0 || i+p >= h || j+q < 0 || j+q >= w)
                             continue;
+                       /*
+                        * An additional special case not mentioned
+                        * above: if a grid dimension is 2xn then
+                        * we do not average across that dimension
+                        * at all. Otherwise a 2x2 grid would
+                        * contain four identical squares.
+                        */
+                       if ((h==2 && p!=0) || (w==2 && q!=0))
+                           continue;
                         n++;
                         sx += fgrid[(i+p)*w+(j+q)];
                     }
@@ -303,7 +312,7 @@ static void generate(random_state *rs, int w, int h, unsigned char *retgrid)
 
     for (i = 0; i < h; i++) {
         for (j = 0; j < w; j++) {
-            retgrid[i*w+j] = (fgrid[i*w+j] > threshold ? GRID_FULL :
+            retgrid[i*w+j] = (fgrid[i*w+j] >= threshold ? GRID_FULL :
                               GRID_EMPTY);
         }
     }
@@ -408,6 +417,34 @@ static unsigned char *generate_soluble(random_state *rs, int w, int h)
 
         generate(rs, w, h, grid);
 
+        /*
+         * The game is a bit too easy if any row or column is
+         * completely black or completely white. An exception is
+         * made for rows/columns that are under 3 squares,
+         * otherwise nothing will ever be successfully generated.
+         */
+        ok = TRUE;
+        if (w > 2) {
+            for (i = 0; i < h; i++) {
+                int colours = 0;
+                for (j = 0; j < w; j++)
+                    colours |= (grid[i*w+j] == GRID_FULL ? 2 : 1);
+                if (colours != 3)
+                    ok = FALSE;
+            }
+        }
+        if (h > 2) {
+            for (j = 0; j < w; j++) {
+                int colours = 0;
+                for (i = 0; i < h; i++)
+                    colours |= (grid[i*w+j] == GRID_FULL ? 2 : 1);
+                if (colours != 3)
+                    ok = FALSE;
+            }
+        }
+        if (!ok)
+            continue;
+
         memset(matrix, 0, w*h);
 
         do {