+ * We have now constructed a grid of the size specified in
+ * params2. Now we extend it into a grid of the size specified
+ * in params. We do this in two passes: we extend it vertically
+ * until it's the right height, then we transpose it, then
+ * extend it vertically again (getting it effectively the right
+ * width), then finally transpose again.
+ */
+ for (i = 0; i < 2; i++) {
+ int *grid2, *expand, *where;
+ game_params params3real, *params3 = ¶ms3real;
+
+#ifdef GENERATION_DIAGNOSTICS
+ printf("before expansion:\n");
+ display_grid(params2, grid, NULL, TRUE);
+#endif
+
+ /*
+ * Set up the new grid.
+ */
+ grid2 = snewn(params2->w * params->h, int);
+ expand = snewn(params2->h-1, int);
+ where = snewn(params2->w, int);
+ params3->w = params2->w;
+ params3->h = params->h;
+
+ /*
+ * Decide which horizontal edges are going to get expanded,
+ * and by how much.
+ */
+ for (y = 0; y < params2->h-1; y++)
+ expand[y] = 0;
+ for (y = params2->h; y < params->h; y++) {
+ x = random_upto(rs, params2->h-1);
+ expand[x]++;
+ }
+
+#ifdef GENERATION_DIAGNOSTICS
+ printf("expand[] = {");
+ for (y = 0; y < params2->h-1; y++)
+ printf(" %d", expand[y]);
+ printf(" }\n");
+#endif
+
+ /*
+ * Perform the expansion. The way this works is that we
+ * alternately:
+ *
+ * - copy a row from grid into grid2
+ *
+ * - invent some number of additional rows in grid2 where
+ * there was previously only a horizontal line between
+ * rows in grid, and make random decisions about where
+ * among these to place each rectangle edge that ran
+ * along this line.
+ */
+ for (y = y2 = y2last = 0; y < params2->h; y++) {
+ /*
+ * Copy a single line from row y of grid into row y2 of
+ * grid2.
+ */
+ for (x = 0; x < params2->w; x++) {
+ int val = index(params2, grid, x, y);
+ if (val / params2->w == y && /* rect starts on this line */
+ (y2 == 0 || /* we're at the very top, or... */
+ index(params3, grid2, x, y2-1) / params3->w < y2last
+ /* this rect isn't already started */))
+ index(params3, grid2, x, y2) =
+ INDEX(params3, val % params2->w, y2);
+ else
+ index(params3, grid2, x, y2) =
+ index(params3, grid2, x, y2-1);
+ }
+
+ /*
+ * If that was the last line, terminate the loop early.
+ */
+ if (++y2 == params3->h)
+ break;
+
+ y2last = y2;
+
+ /*
+ * Invent some number of additional lines. First walk
+ * along this line working out where to put all the
+ * edges that coincide with it.
+ */
+ yx = -1;
+ for (x = 0; x < params2->w; x++) {
+ if (index(params2, grid, x, y) !=
+ index(params2, grid, x, y+1)) {
+ /*
+ * This is a horizontal edge, so it needs
+ * placing.
+ */
+ if (x == 0 ||
+ (index(params2, grid, x-1, y) !=
+ index(params2, grid, x, y) &&
+ index(params2, grid, x-1, y+1) !=
+ index(params2, grid, x, y+1))) {
+ /*
+ * Here we have the chance to make a new
+ * decision.
+ */
+ yx = random_upto(rs, expand[y]+1);
+ } else {
+ /*
+ * Here we just reuse the previous value of
+ * yx.
+ */
+ }
+ } else
+ yx = -1;
+ where[x] = yx;
+ }
+
+ for (yx = 0; yx < expand[y]; yx++) {
+ /*
+ * Invent a single row. For each square in the row,
+ * we copy the grid entry from the square above it,
+ * unless we're starting the new rectangle here.
+ */
+ for (x = 0; x < params2->w; x++) {
+ if (yx == where[x]) {
+ int val = index(params2, grid, x, y+1);
+ val %= params2->w;
+ val = INDEX(params3, val, y2);
+ index(params3, grid2, x, y2) = val;
+ } else
+ index(params3, grid2, x, y2) =
+ index(params3, grid2, x, y2-1);
+ }
+
+ y2++;
+ }
+ }
+
+ sfree(expand);
+ sfree(where);
+
+#ifdef GENERATION_DIAGNOSTICS
+ printf("after expansion:\n");
+ display_grid(params3, grid2, NULL, TRUE);
+#endif
+ /*
+ * Transpose.
+ */
+ params2->w = params3->h;
+ params2->h = params3->w;
+ sfree(grid);
+ grid = snewn(params2->w * params2->h, int);
+ for (x = 0; x < params2->w; x++)
+ for (y = 0; y < params2->h; y++) {
+ int idx1 = INDEX(params2, x, y);
+ int idx2 = INDEX(params3, y, x);
+ int tmp;
+
+ tmp = grid2[idx2];
+ tmp = (tmp % params3->w) * params2->w + (tmp / params3->w);
+ grid[idx1] = tmp;
+ }
+
+ sfree(grid2);
+
+ {
+ int tmp;
+ tmp = params->w;
+ params->w = params->h;
+ params->h = tmp;
+ }
+
+#ifdef GENERATION_DIAGNOSTICS
+ printf("after transposition:\n");
+ display_grid(params2, grid, NULL, TRUE);
+#endif
+ }
+
+ /*