+ * End of solver code.
+ */
+
+/* ----------------------------------------------------------------------
+ * Solo filled-grid generator.
+ *
+ * This grid generator works by essentially trying to solve a grid
+ * starting from no clues, and not worrying that there's more than
+ * one possible solution. Unfortunately, it isn't computationally
+ * feasible to do this by calling the above solver with an empty
+ * grid, because that one needs to allocate a lot of scratch space
+ * at every recursion level. Instead, I have a much simpler
+ * algorithm which I shamelessly copied from a Python solver
+ * written by Andrew Wilkinson (which is GPLed, but I've reused
+ * only ideas and no code). It mostly just does the obvious
+ * recursive thing: pick an empty square, put one of the possible
+ * digits in it, recurse until all squares are filled, backtrack
+ * and change some choices if necessary.
+ *
+ * The clever bit is that every time it chooses which square to
+ * fill in next, it does so by counting the number of _possible_
+ * numbers that can go in each square, and it prioritises so that
+ * it picks a square with the _lowest_ number of possibilities. The
+ * idea is that filling in lots of the obvious bits (particularly
+ * any squares with only one possibility) will cut down on the list
+ * of possibilities for other squares and hence reduce the enormous
+ * search space as much as possible as early as possible.
+ */
+
+/*
+ * Internal data structure used in gridgen to keep track of
+ * progress.
+ */
+struct gridgen_coord { int x, y, r; };
+struct gridgen_usage {
+ int cr;
+ struct block_structure *blocks;
+ /* grid is a copy of the input grid, modified as we go along */
+ digit *grid;
+ /* row[y*cr+n-1] TRUE if digit n has been placed in row y */
+ unsigned char *row;
+ /* col[x*cr+n-1] TRUE if digit n has been placed in row x */
+ unsigned char *col;
+ /* blk[(y*c+x)*cr+n-1] TRUE if digit n has been placed in block (x,y) */
+ unsigned char *blk;
+ /* diag[i*cr+n-1] TRUE if digit n has been placed in diagonal i */
+ unsigned char *diag;
+ /* This lists all the empty spaces remaining in the grid. */
+ struct gridgen_coord *spaces;
+ int nspaces;
+ /* If we need randomisation in the solve, this is our random state. */
+ random_state *rs;
+};
+
+static void gridgen_place(struct gridgen_usage *usage, int x, int y, digit n,
+ int placing)
+{
+ int cr = usage->cr;
+ usage->row[y*cr+n-1] = usage->col[x*cr+n-1] =
+ usage->blk[usage->blocks->whichblock[y*cr+x]*cr+n-1] = placing;
+ if (usage->diag) {
+ if (ondiag0(y*cr+x))
+ usage->diag[n-1] = placing;
+ if (ondiag1(y*cr+x))
+ usage->diag[cr+n-1] = placing;
+ }
+ usage->grid[y*cr+x] = placing ? n : 0;
+}
+
+/*
+ * The real recursive step in the generating function.
+ *
+ * Return values: 1 means solution found, 0 means no solution
+ * found on this branch.
+ */
+static int gridgen_real(struct gridgen_usage *usage, digit *grid, int *steps)
+{
+ int cr = usage->cr;
+ int i, j, n, sx, sy, bestm, bestr, ret;
+ int *digits;
+
+ /*
+ * Firstly, check for completion! If there are no spaces left
+ * in the grid, we have a solution.
+ */
+ if (usage->nspaces == 0)
+ return TRUE;
+
+ /*
+ * Next, abandon generation if we went over our steps limit.
+ */
+ if (*steps <= 0)
+ return FALSE;
+ (*steps)--;
+
+ /*
+ * Otherwise, there must be at least one space. Find the most
+ * constrained space, using the `r' field as a tie-breaker.
+ */
+ bestm = cr+1; /* so that any space will beat it */
+ bestr = 0;
+ i = sx = sy = -1;
+ for (j = 0; j < usage->nspaces; j++) {
+ int x = usage->spaces[j].x, y = usage->spaces[j].y;
+ int m;
+
+ /*
+ * Find the number of digits that could go in this space.
+ */
+ m = 0;
+ for (n = 0; n < cr; n++)
+ if (!usage->row[y*cr+n] && !usage->col[x*cr+n] &&
+ !usage->blk[usage->blocks->whichblock[y*cr+x]*cr+n] &&
+ (!usage->diag || ((!ondiag0(y*cr+x) || !usage->diag[n]) &&
+ (!ondiag1(y*cr+x) || !usage->diag[cr+n]))))
+ m++;
+
+ if (m < bestm || (m == bestm && usage->spaces[j].r < bestr)) {
+ bestm = m;
+ bestr = usage->spaces[j].r;
+ sx = x;
+ sy = y;
+ i = j;
+ }
+ }
+
+ /*
+ * Swap that square into the final place in the spaces array,
+ * so that decrementing nspaces will remove it from the list.
+ */
+ if (i != usage->nspaces-1) {
+ struct gridgen_coord t;
+ t = usage->spaces[usage->nspaces-1];
+ usage->spaces[usage->nspaces-1] = usage->spaces[i];
+ usage->spaces[i] = t;
+ }
+
+ /*
+ * Now we've decided which square to start our recursion at,
+ * simply go through all possible values, shuffling them
+ * randomly first if necessary.
+ */
+ digits = snewn(bestm, int);
+ j = 0;
+ for (n = 0; n < cr; n++)
+ if (!usage->row[sy*cr+n] && !usage->col[sx*cr+n] &&
+ !usage->blk[usage->blocks->whichblock[sy*cr+sx]*cr+n] &&
+ (!usage->diag || ((!ondiag0(sy*cr+sx) || !usage->diag[n]) &&
+ (!ondiag1(sy*cr+sx) || !usage->diag[cr+n])))) {
+ digits[j++] = n+1;
+ }
+
+ if (usage->rs)
+ shuffle(digits, j, sizeof(*digits), usage->rs);
+
+ /* And finally, go through the digit list and actually recurse. */
+ ret = FALSE;
+ for (i = 0; i < j; i++) {
+ n = digits[i];
+
+ /* Update the usage structure to reflect the placing of this digit. */
+ gridgen_place(usage, sx, sy, n, TRUE);
+ usage->nspaces--;
+
+ /* Call the solver recursively. Stop when we find a solution. */
+ if (gridgen_real(usage, grid, steps)) {
+ ret = TRUE;
+ break;
+ }
+
+ /* Revert the usage structure. */
+ gridgen_place(usage, sx, sy, n, FALSE);
+ usage->nspaces++;
+ }
+
+ sfree(digits);
+ return ret;
+}
+
+/*
+ * Entry point to generator. You give it parameters and a starting
+ * grid, which is simply an array of cr*cr digits.
+ */
+static int gridgen(int cr, struct block_structure *blocks, int xtype,
+ digit *grid, random_state *rs, int maxsteps)
+{
+ struct gridgen_usage *usage;
+ int x, y, ret;
+
+ /*
+ * Clear the grid to start with.
+ */
+ memset(grid, 0, cr*cr);
+
+ /*
+ * Create a gridgen_usage structure.
+ */
+ usage = snew(struct gridgen_usage);
+
+ usage->cr = cr;
+ usage->blocks = blocks;
+
+ usage->grid = grid;
+
+ usage->row = snewn(cr * cr, unsigned char);
+ usage->col = snewn(cr * cr, unsigned char);
+ usage->blk = snewn(cr * cr, unsigned char);
+ memset(usage->row, FALSE, cr * cr);
+ memset(usage->col, FALSE, cr * cr);
+ memset(usage->blk, FALSE, cr * cr);
+
+ if (xtype) {
+ usage->diag = snewn(2 * cr, unsigned char);
+ memset(usage->diag, FALSE, 2 * cr);
+ } else {
+ usage->diag = NULL;
+ }
+
+ /*
+ * Begin by filling in the whole top row with randomly chosen
+ * numbers. This cannot introduce any bias or restriction on
+ * the available grids, since we already know those numbers
+ * are all distinct so all we're doing is choosing their
+ * labels.
+ */
+ for (x = 0; x < cr; x++)
+ grid[x] = x+1;
+ shuffle(grid, cr, sizeof(*grid), rs);
+ for (x = 0; x < cr; x++)
+ gridgen_place(usage, x, 0, grid[x], TRUE);
+
+ usage->spaces = snewn(cr * cr, struct gridgen_coord);
+ usage->nspaces = 0;
+
+ usage->rs = rs;
+
+ /*
+ * Initialise the list of grid spaces, taking care to leave
+ * out the row I've already filled in above.
+ */
+ for (y = 1; y < cr; y++) {
+ for (x = 0; x < cr; x++) {
+ usage->spaces[usage->nspaces].x = x;
+ usage->spaces[usage->nspaces].y = y;
+ usage->spaces[usage->nspaces].r = random_bits(rs, 31);
+ usage->nspaces++;
+ }
+ }
+
+ /*
+ * Run the real generator function.
+ */
+ ret = gridgen_real(usage, grid, &maxsteps);
+
+ /*
+ * Clean up the usage structure now we have our answer.
+ */
+ sfree(usage->spaces);
+ sfree(usage->blk);
+ sfree(usage->col);
+ sfree(usage->row);
+ sfree(usage);
+
+ return ret;
+}
+
+/* ----------------------------------------------------------------------
+ * End of grid generator code.