shithub: puzzles

Download patch

ref: 89c438e149a91fffa74b2669f7e0cd05abc3420f
parent: 7abf85a9c6b460698994d9cfa538b7b26fed5e87
author: Simon Tatham <anakin@pobox.com>
date: Thu Apr 20 10:06:43 EDT 2023

Declare all dsfs as a dedicated type name 'DSF'.

In this commit, 'DSF' is simply a typedef for 'int', so that the new
declaration form 'DSF *' translates to the same type 'int *' that dsfs
have always had. So all we're doing here is mechanically changing type
declarations throughout the code.

--- a/auxiliary/divvy-test.c
+++ b/auxiliary/divvy-test.c
@@ -7,7 +7,7 @@
 
 int main(int argc, char **argv)
 {
-    int *dsf;
+    DSF *dsf;
     int i;
     int w = 9, h = 4, k = 6, tries = 100;
     random_state *rs;
--- a/bridges.c
+++ b/bridges.c
@@ -139,8 +139,8 @@
 typedef unsigned int grid_type; /* change me later if we invent > 16 bits of flags. */
 
 struct solver_state {
-    int *dsf, *comptspaces;
-    int *tmpdsf, *tmpcompspaces;
+    DSF *dsf, *tmpdsf;
+    int *comptspaces, *tmpcompspaces;
     int refcount;
 };
 
@@ -1142,7 +1142,7 @@
 {
     int i, wh = state->w*state->h, d1, d2;
     int x, y, x2, y2;
-    int *dsf = state->solver->dsf;
+    DSF *dsf = state->solver->dsf;
     struct island *is, *is_join;
 
     /* Initialise dsf. */
@@ -1187,7 +1187,8 @@
 static bool map_group_check(game_state *state, int canon, bool warn,
                             int *nislands_r)
 {
-    int *dsf = state->solver->dsf, nislands = 0;
+    DSF *dsf = state->solver->dsf;
+    int nislands = 0;
     int x, y, i;
     bool allfull = true;
     struct island *is;
@@ -1219,7 +1220,8 @@
 
 static bool map_group_full(game_state *state, int *ngroups_r)
 {
-    int *dsf = state->solver->dsf, ngroups = 0;
+    DSF *dsf = state->solver->dsf;
+    int ngroups = 0;
     int i;
     bool anyfull = false;
     struct island *is;
@@ -1274,7 +1276,8 @@
 static void solve_join(struct island *is, int direction, int n, bool is_max)
 {
     struct island *is_orth;
-    int d1, d2, *dsf = is->state->solver->dsf;
+    int d1, d2;
+    DSF *dsf = is->state->solver->dsf;
     game_state *state = is->state; /* for DINDEX */
 
     is_orth = INDEX(is->state, gridi,
@@ -1389,7 +1392,8 @@
 static bool solve_island_checkloop(struct island *is, int direction)
 {
     struct island *is_orth;
-    int *dsf = is->state->solver->dsf, d1, d2;
+    DSF *dsf = is->state->solver->dsf;
+    int d1, d2;
     game_state *state = is->state;
 
     if (is->state->allowloops)
@@ -1464,7 +1468,8 @@
 static bool solve_island_subgroup(struct island *is, int direction)
 {
     struct island *is_join;
-    int nislands, *dsf = is->state->solver->dsf;
+    int nislands;
+    DSF *dsf = is->state->solver->dsf;
     game_state *state = is->state;
 
     debug(("..checking subgroups.\n"));
--- a/divvy.c
+++ b/divvy.c
@@ -260,9 +260,10 @@
  * In both of the above suggested use cases, the user would
  * probably want w==h==k, but that isn't a requirement.
  */
-int *divvy_rectangle_attempt(int w, int h, int k, random_state *rs)
+DSF *divvy_rectangle_attempt(int w, int h, int k, random_state *rs)
 {
-    int *order, *queue, *tmp, *own, *sizes, *addable, *retdsf, *tmpdsf;
+    int *order, *queue, *tmp, *own, *sizes, *addable;
+    DSF *retdsf, *tmpdsf;
     bool *removable;
     int wh = w*h;
     int i, j, n, x, y, qhead, qtail;
@@ -654,9 +655,9 @@
     return retdsf;
 }
 
-int *divvy_rectangle(int w, int h, int k, random_state *rs)
+DSF *divvy_rectangle(int w, int h, int k, random_state *rs)
 {
-    int *ret;
+    DSF *ret;
 
     do {
 	ret = divvy_rectangle_attempt(w, h, k, rs);
--- a/dominosa.c
+++ b/dominosa.c
@@ -350,7 +350,8 @@
     struct solver_square **squares_by_number;
     struct findloopstate *fls;
     bool squares_by_number_initialised;
-    int *wh_scratch, *pc_scratch, *pc_scratch2, *dc_scratch, *dsf_scratch;
+    int *wh_scratch, *pc_scratch, *pc_scratch2, *dc_scratch;
+    DSF *dsf_scratch;
 };
 
 static struct solver_scratch *solver_make_scratch(int n)
--- a/dsf.c
+++ b/dsf.c
@@ -61,7 +61,7 @@
     sfree(inverse_elements);
 }*/
 
-void dsf_init(int *dsf, int size)
+void dsf_init(DSF *dsf, int size)
 {
     int i;
 
@@ -74,12 +74,12 @@
      * bits are the number of elements in the tree.  */
 }
 
-void dsf_copy(int *to, int *from, int size)
+void dsf_copy(DSF *to, DSF *from, int size)
 {
     memcpy(to, from, size * sizeof(int));
 }
 
-int *snew_dsf(int size)
+DSF *snew_dsf(int size)
 {
     int *ret;
     
@@ -91,26 +91,26 @@
     return ret;
 }
 
-void dsf_free(int *dsf)
+void dsf_free(DSF *dsf)
 {
     sfree(dsf);
 }
 
-int dsf_canonify(int *dsf, int index)
+int dsf_canonify(DSF *dsf, int index)
 {
     return edsf_canonify(dsf, index, NULL);
 }
 
-void dsf_merge(int *dsf, int v1, int v2)
+void dsf_merge(DSF *dsf, int v1, int v2)
 {
     edsf_merge(dsf, v1, v2, false);
 }
 
-int dsf_size(int *dsf, int index) {
+int dsf_size(DSF *dsf, int index) {
     return dsf[dsf_canonify(dsf, index)] >> 2;
 }
 
-int edsf_canonify(int *dsf, int index, bool *inverse_return)
+int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
 {
     int start_index = index, canonical_index;
     bool inverse = false;
@@ -152,7 +152,7 @@
     return index;
 }
 
-void edsf_merge(int *dsf, int v1, int v2, bool inverse)
+void edsf_merge(DSF *dsf, int v1, int v2, bool inverse)
 {
     bool i1, i2;
 
--- a/filling.c
+++ b/filling.c
@@ -295,7 +295,7 @@
 
 struct solver_state
 {
-    int *dsf;
+    DSF *dsf;
     int *board;
     int *connected;
     int nempty;
@@ -302,7 +302,8 @@
 
     /* Used internally by learn_bitmap_deductions; kept here to avoid
      * mallocing/freeing them every time that function is called. */
-    int *bm, *bmdsf, *bmminsize;
+    int *bm, *bmminsize;
+    DSF *bmdsf;
 };
 
 static void print_board(int *board, int w, int h) {
@@ -396,7 +397,8 @@
     /* Note that if 1 in {w, h} then it's impossible to have a region
      * of size > w*h, so the special case only affects w=h=2. */
 
-    int i, *dsf;
+    int i;
+    DSF *dsf;
     bool change;
 
     assert(w >= 1);
@@ -467,7 +469,7 @@
     dsf_free(dsf);
 }
 
-static void merge(int *dsf, int *connected, int a, int b) {
+static void merge(DSF *dsf, int *connected, int a, int b) {
     int c;
     assert(dsf);
     assert(connected);
@@ -543,7 +545,7 @@
     return n == 0;
 }
 
-static int expandsize(const int *board, int *dsf, int w, int h, int i, int n) {
+static int expandsize(const int *board, DSF *dsf, int w, int h, int i, int n) {
     int j;
     int nhits = 0;
     int hits[4];
@@ -844,7 +846,7 @@
 {
     const int sz = w * h;
     int *bm = s->bm;
-    int *dsf = s->bmdsf;
+    DSF *dsf = s->bmdsf;
     int *minsize = s->bmminsize;
     int x, y, i, j, n;
     bool learn = false;
@@ -1128,7 +1130,7 @@
     return !ss.nempty;
 }
 
-static int *make_dsf(int *dsf, int *board, const int w, const int h) {
+static DSF *make_dsf(DSF *dsf, int *board, const int w, const int h) {
     const int sz = w * h;
     int i;
 
@@ -1154,7 +1156,8 @@
 {
     const int sz = w * h;
     int *shuf = snewn(sz, int), i;
-    int *dsf, *next;
+    DSF *dsf;
+    int *next;
 
     for (i = 0; i < sz; ++i) shuf[i] = i;
     shuffle(shuf, sz, sizeof (int), rs);
@@ -1451,7 +1454,8 @@
     int tilesize;
     bool started;
     int *v, *flags;
-    int *dsf_scratch, *border_scratch;
+    DSF *dsf_scratch;
+    int *border_scratch;
 };
 
 static char *interpret_move(const game_state *state, game_ui *ui,
@@ -1614,7 +1618,7 @@
         const int w = new_state->shared->params.w;
         const int h = new_state->shared->params.h;
         const int sz = w * h;
-        int *dsf = make_dsf(NULL, new_state->board, w, h);
+        DSF *dsf = make_dsf(NULL, new_state->board, w, h);
         int i;
         for (i = 0; i < sz && new_state->board[i] == dsf_size(dsf, i); ++i);
         dsf_free(dsf);
--- a/galaxies.c
+++ b/galaxies.c
@@ -192,7 +192,7 @@
                            or -1 if stale. */
 };
 
-static bool check_complete(const game_state *state, int *dsf, int *colours);
+static bool check_complete(const game_state *state, DSF *dsf, int *colours);
 static int solver_state_inner(game_state *state, int maxdiff, int depth);
 static int solver_state(game_state *state, int maxdiff);
 static int solver_obvious(game_state *state);
@@ -1799,7 +1799,7 @@
     game_state *state;
     int sz;             /* state->sx * state->sy */
     space **scratch;    /* size sz */
-    int *dsf;           /* size sz */
+    DSF *dsf;           /* size sz */
     int *iscratch;      /* size sz */
 } solver_ctx;
 
@@ -3066,7 +3066,7 @@
 }
 #endif
 
-static bool check_complete(const game_state *state, int *dsf, int *colours)
+static bool check_complete(const game_state *state, DSF *dsf, int *colours)
 {
     int w = state->w, h = state->h;
     int x, y, i;
@@ -3944,7 +3944,8 @@
     int w = state->w, h = state->h;
     int white, black, blackish;
     int x, y, i, j;
-    int *colours, *dsf;
+    int *colours;
+    DSF *dsf;
     int *coords = NULL;
     int ncoords = 0, coordsize = 0;
 
--- a/grid.c
+++ b/grid.c
@@ -364,7 +364,7 @@
 static void grid_trim_vigorously(grid *g)
 {
     int *dotpairs, *faces, *dots;
-    int *dsf;
+    DSF *dsf;
     int i, j, k, size, newfaces, newdots;
 
     /*
--- a/keen.c
+++ b/keen.c
@@ -73,7 +73,7 @@
 struct clues {
     int refcount;
     int w;
-    int *dsf;
+    DSF *dsf;
     long *clues;
 };
 
@@ -681,7 +681,7 @@
     return true;
 }
 
-static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff)
+static int solver(int w, DSF *dsf, long *clues, digit *soln, int maxdiff)
 {
     int a = w*w;
     struct solver_ctx ctx;
@@ -744,7 +744,7 @@
  * Grid generation.
  */
 
-static char *encode_block_structure(char *p, int w, int *dsf)
+static char *encode_block_structure(char *p, int w, DSF *dsf)
 {
     int i, currrun = 0;
     char *orig, *q, *r, c;
@@ -819,7 +819,7 @@
     return q;
 }
 
-static const char *parse_block_structure(const char **p, int w, int *dsf)
+static const char *parse_block_structure(const char **p, int w, DSF *dsf)
 {
     int a = w*w;
     int pos = 0;
@@ -894,7 +894,8 @@
 {
     int w = params->w, a = w*w;
     digit *grid, *soln;
-    int *order, *revorder, *singletons, *dsf;
+    int *order, *revorder, *singletons;
+    DSF *dsf;
     long *clues, *cluevals;
     int i, j, k, n, x, y, ret;
     int diff = params->diff;
@@ -1299,7 +1300,7 @@
 static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, a = w*w;
-    int *dsf;
+    DSF *dsf;
     const char *ret;
     const char *p = desc;
     int i;
@@ -2243,7 +2244,7 @@
  * single polygon.
  */
 static void outline_block_structure(drawing *dr, game_drawstate *ds,
-				    int w, int *dsf, int ink)
+				    int w, DSF *dsf, int ink)
 {
     int a = w*w;
     int *coords;
--- a/loopy.c
+++ b/loopy.c
@@ -157,7 +157,7 @@
     char *face_yes_count;
     char *face_no_count;
     bool *dot_solved, *face_solved;
-    int *dotdsf;
+    DSF *dotdsf;
 
     /* Information for Normal level deductions:
      * For each dline, store a bitmask for whether we know:
@@ -166,7 +166,7 @@
     char *dlines;
 
     /* Hard level information */
-    int *linedsf;
+    DSF *linedsf;
 } solver_state;
 
 /*
@@ -1545,7 +1545,8 @@
     grid *g = state->game_grid;
     int i;
     bool ret;
-    int *dsf, *component_state;
+    DSF *dsf;
+    int *component_state;
     int nsilly, nloop, npath, largest_comp, largest_size, total_pathsize;
     enum { COMP_NONE, COMP_LOOP, COMP_PATH, COMP_SILLY, COMP_EMPTY };
 
@@ -1993,7 +1994,7 @@
 {
     game_state *state = sstate->state;
     int diff = DIFF_MAX;
-    int *linedsf = sstate->linedsf;
+    DSF *linedsf = sstate->linedsf;
 
     if (unknown_count == 2) {
         /* Lines are known alike/opposite, depending on inv. */
--- a/map.c
+++ b/map.c
@@ -1725,7 +1725,7 @@
     bool state;
     const char *p = *desc;
     const char *err = NULL;
-    int *dsf = snew_dsf(wh);
+    DSF *dsf = snew_dsf(wh);
 
     pos = -1;
     state = false;
--- a/net.c
+++ b/net.c
@@ -462,7 +462,7 @@
     unsigned char *tilestate;
     unsigned char *edgestate;
     int *deadends;
-    int *equivalence;
+    DSF *equivalence;
     struct todo *todo;
     int i, j, x, y;
     int area;
--- a/palisade.c
+++ b/palisade.c
@@ -186,7 +186,7 @@
     const game_params *params;  /* also in shared_state */
     clue *clues;                /* also in shared_state */
     borderflag *borders;        /* also in game_state */
-    int *dsf;                   /* particular to the solver */
+    DSF *dsf;                   /* particular to the solver */
 } solver_ctx;
 
 /* Deductions:
@@ -506,7 +506,7 @@
 }
 
 /* build connected components in `dsf', along the lines of `borders'. */
-static void build_dsf(int w, int h, borderflag *border, int *dsf, bool black)
+static void build_dsf(int w, int h, borderflag *border, DSF *dsf, bool black)
 {
     int x, y;
 
@@ -527,7 +527,7 @@
 {
     int w = params->w, h = params->h, wh = w*h, k = params->k;
     int i, x, y;
-    int *dsf = snew_dsf(wh);
+    DSF *dsf = snew_dsf(wh);
 
     build_dsf(w, h, border, dsf, true);
 
@@ -631,7 +631,8 @@
 
     char *soln = snewa(*aux, wh + 2);
     int *shuf = snewn(wh, int);
-    int *dsf = NULL, i, r, c;
+    DSF *dsf = NULL;
+    int i, r, c;
 
     int attempts = 0;
 
@@ -1171,7 +1172,7 @@
 {
     int w = state->shared->params.w, h = state->shared->params.h, wh = w*h;
     int r, c, flash = ((int) (flashtime * 5 / FLASH_TIME)) % 2;
-    int *black_border_dsf = snew_dsf(wh), *yellow_border_dsf = snew_dsf(wh);
+    DSF *black_border_dsf = snew_dsf(wh), *yellow_border_dsf = snew_dsf(wh);
     int k = state->shared->params.k;
 
     if (!ds->grid) {
--- a/pearl.c
+++ b/pearl.c
@@ -296,7 +296,8 @@
 {
     int W = 2*w+1, H = 2*h+1;
     short *workspace;
-    int *dsf, *dsfsize;
+    DSF *dsf;
+    int *dsfsize;
     int x, y, b, d;
     int ret = -1;
 
@@ -1531,7 +1532,7 @@
 
 /* Returns false if the state is invalid. */
 static bool dsf_update_completion(game_state *state, int ax, int ay, char dir,
-                                 int *dsf)
+                                 DSF *dsf)
 {
     int w = state->shared->w /*, h = state->shared->h */;
     int ac = ay*w+ax, bx, by, bc;
@@ -1556,7 +1557,8 @@
 {
     int w = state->shared->w, h = state->shared->h, x, y, i, d;
     bool had_error = false;
-    int *dsf, *component_state;
+    DSF *dsf;
+    int *component_state;
     int nsilly, nloop, npath, largest_comp, largest_size, total_pathsize;
     enum { COMP_NONE, COMP_LOOP, COMP_PATH, COMP_SILLY, COMP_EMPTY };
 
--- a/puzzles.h
+++ b/puzzles.h
@@ -426,19 +426,20 @@
 /*
  * dsf.c
  */
-int *snew_dsf(int size);
-void dsf_free(int *dsf);
+typedef int DSF;
+DSF *snew_dsf(int size);
+void dsf_free(DSF *dsf);
 
-void print_dsf(int *dsf, int size);
+void print_dsf(DSF *dsf, int size);
 
-void dsf_copy(int *to, int *from, int size);
+void dsf_copy(DSF *to, DSF *from, int size);
 
 /* Return the canonical element of the equivalence class containing element
  * val.  If 'inverse' is non-NULL, this function will put into it a flag
  * indicating whether the canonical element is inverse to val. */
-int edsf_canonify(int *dsf, int val, bool *inverse);
-int dsf_canonify(int *dsf, int val);
-int dsf_size(int *dsf, int val);
+int edsf_canonify(DSF *dsf, int val, bool *inverse);
+int dsf_canonify(DSF *dsf, int val);
+int dsf_size(DSF *dsf, int val);
 
 /* Allow the caller to specify that two elements should be in the same
  * equivalence class.  If 'inverse' is true, the elements are actually opposite
@@ -445,9 +446,9 @@
  * to one another in some sense.  This function will fail an assertion if the
  * caller gives it self-contradictory data, ie if two elements are claimed to
  * be both opposite and non-opposite. */
-void edsf_merge(int *dsf, int v1, int v2, bool inverse);
-void dsf_merge(int *dsf, int v1, int v2);
-void dsf_init(int *dsf, int len);
+void edsf_merge(DSF *dsf, int v1, int v2, bool inverse);
+void dsf_merge(DSF *dsf, int v1, int v2);
+void dsf_init(DSF *dsf, int len);
 
 /*
  * tdq.c
@@ -565,9 +566,9 @@
  * divvy.c
  */
 /* divides w*h rectangle into pieces of size k. Returns w*h dsf. */
-int *divvy_rectangle(int w, int h, int k, random_state *rs);
+DSF *divvy_rectangle(int w, int h, int k, random_state *rs);
 /* Same, but only tries once, and may fail. (Exposed for test program.) */
-int *divvy_rectangle_attempt(int w, int h, int k, random_state *rs);
+DSF *divvy_rectangle_attempt(int w, int h, int k, random_state *rs);
 
 /*
  * findloop.c
--- a/range.c
+++ b/range.c
@@ -1421,7 +1421,7 @@
 static bool find_errors(const game_state *state, bool *report)
 {
     int const w = state->params.w, h = state->params.h, n = w * h;
-    int *dsf;
+    DSF *dsf;
 
     int r, c, i;
 
--- a/signpost.c
+++ b/signpost.c
@@ -62,7 +62,7 @@
     int *nums;                  /* numbers, size n */
     unsigned int *flags;        /* flags, size n */
     int *next, *prev;           /* links to other cell indexes, size n (-1 absent) */
-    int *dsf;                   /* connects regions with a dsf. */
+    DSF *dsf;                   /* connects regions with a dsf. */
     int *numsi;                 /* for each number, which index is it in? (-1 absent) */
 };
 
--- a/singles.c
+++ b/singles.c
@@ -421,7 +421,7 @@
     sfree(dbg);
 }
 
-static void connect_if_same(game_state *state, int *dsf, int i1, int i2)
+static void connect_if_same(game_state *state, DSF *dsf, int i1, int i2)
 {
     int c1, c2;
 
@@ -433,7 +433,7 @@
     dsf_merge(dsf, c1, c2);
 }
 
-static void connect_dsf(game_state *state, int *dsf)
+static void connect_dsf(game_state *state, DSF *dsf)
 {
     int x, y, i;
 
@@ -498,7 +498,7 @@
 
 static bool check_complete(game_state *state, unsigned flags)
 {
-    int *dsf = snew_dsf(state->n);
+    DSF *dsf = snew_dsf(state->n);
     int x, y, i, error = 0, nwhite, w = state->w, h = state->h;
 
     if (flags & CC_MARK_ERRORS) {
--- a/slant.c
+++ b/slant.c
@@ -244,7 +244,7 @@
      * Disjoint set forest which tracks the connected sets of
      * points.
      */
-    int *connected;
+    DSF *connected;
 
     /*
      * Counts the number of possible exits from each connected set
@@ -265,7 +265,7 @@
      * Another disjoint set forest. This one tracks _squares_ which
      * are known to slant in the same direction.
      */
-    int *equiv;
+    DSF *equiv;
 
     /*
      * Stores slash values which we know for an equivalence class.
@@ -336,7 +336,7 @@
  * Wrapper on dsf_merge() which updates the `exits' and `border'
  * arrays.
  */
-static void merge_vertices(int *connected,
+static void merge_vertices(DSF *connected,
 			   struct solver_scratch *sc, int i, int j)
 {
     int exits = -1;
@@ -382,7 +382,7 @@
 
 static void fill_square(int w, int h, int x, int y, int v,
 			signed char *soln,
-			int *connected, struct solver_scratch *sc)
+			DSF *connected, struct solver_scratch *sc)
 {
     int W = w+1 /*, H = h+1 */;
 
@@ -997,7 +997,8 @@
 {
     int W = w+1, H = h+1;
     int x, y, i;
-    int *connected, *indices;
+    DSF *connected;
+    int *indices;
 
     /*
      * Clear the output.
--- a/solo.c
+++ b/solo.c
@@ -3226,7 +3226,7 @@
     return ret;
 }
 
-static void dsf_to_blocks(int *dsf, struct block_structure *blocks,
+static void dsf_to_blocks(DSF *dsf, struct block_structure *blocks,
 			  int min_expected, int max_expected)
 {
     int cr = blocks->c * blocks->r, area = cr * cr;
@@ -3689,7 +3689,7 @@
          * constructing the block structure.
          */
 	if (r == 1) {		       /* jigsaw mode */
-	    int *dsf = divvy_rectangle(cr, cr, cr, rs);
+	    DSF *dsf = divvy_rectangle(cr, cr, cr, rs);
 
 	    dsf_to_blocks (dsf, blocks, cr, cr);
 
@@ -3908,12 +3908,12 @@
  * end of the block spec, and return an error string or NULL if everything
  * is OK. The DSF is stored in *PDSF.
  */
-static const char *spec_to_dsf(const char **pdesc, int **pdsf,
+static const char *spec_to_dsf(const char **pdesc, DSF **pdsf,
                                int cr, int area)
 {
     const char *desc = *pdesc;
     int pos = 0;
-    int *dsf;
+    DSF *dsf;
 
     *pdsf = dsf = snew_dsf(area);
 
@@ -4013,7 +4013,7 @@
                                        int min_nr_squares, int max_nr_squares)
 {
     const char *err;
-    int *dsf;
+    DSF *dsf;
 
     err = spec_to_dsf(pdesc, &dsf, cr, area);
     if (err) {
@@ -4166,7 +4166,7 @@
 
     if (r == 1) {
 	const char *err;
-	int *dsf;
+	DSF *dsf;
 	assert(*desc == ',');
 	desc++;
 	err = spec_to_dsf(&desc, &dsf, cr, area);
@@ -4184,7 +4184,7 @@
 
     if (params->killer) {
 	const char *err;
-	int *dsf;
+	DSF *dsf;
 	assert(*desc == ',');
 	desc++;
 	err = spec_to_dsf(&desc, &dsf, cr, area);
--- a/tents.c
+++ b/tents.c
@@ -2006,7 +2006,8 @@
 {
     int w = state->p.w, h = state->p.h;
     int *ret = snewn(w*h + w + h, int);
-    int *tmp = snewn(w*h, int), *dsf;
+    int *tmp = snewn(w*h, int);
+    DSF *dsf;
     int x, y;
 
     /*
--- a/tracks.c
+++ b/tracks.c
@@ -914,7 +914,7 @@
 }
 
 struct solver_scratch {
-    int *dsf;
+    DSF *dsf;
 };
 
 static int solve_set_sflag(game_state *state, int x, int y,
@@ -1316,7 +1316,7 @@
 }
 
 static int solve_check_loop_sub(game_state *state, int x, int y, int dir,
-                                int *dsf, int startc, int endc)
+                                DSF *dsf, int startc, int endc)
 {
     int w = state->p.w, h = state->p.h, i = y*w+x, j, k;
     bool satisfied = true;
@@ -1368,7 +1368,8 @@
 static int solve_check_loop(game_state *state)
 {
     int w = state->p.w, h = state->p.h, x, y, i, j, did = 0;
-    int *dsf, startc, endc;
+    DSF *dsf;
+    int startc, endc;
 
     /* TODO eventually we should pull this out into a solver struct and keep it
        updated as we connect squares. For now we recreate it every time we try
@@ -1784,7 +1785,7 @@
 }
 
 static void dsf_update_completion(game_state *state, int ax, int ay,
-                                  char dir, int *dsf)
+                                  char dir, DSF *dsf)
 {
     int w = state->p.w, ai = ay*w+ax, bx, by, bi;
 
@@ -1858,7 +1859,8 @@
     int w = state->p.w, h = state->p.h, x, y, i, target;
     bool ret = true, pathret;
     int ntrack, nnotrack, ntrackcomplete;
-    int *dsf, pathclass;
+    DSF *dsf;
+    int pathclass;
     struct findloopstate *fls;
     struct tracks_neighbour_ctx ctx;
 
--- a/unfinished/separate.c
+++ b/unfinished/separate.c
@@ -189,7 +189,7 @@
     /*
      * Tracks connectedness between squares.
      */
-    int *dsf;
+    DSF *dsf;
 
     /*
      * size[dsf_canonify(dsf, yx)] tracks the size of the
@@ -514,7 +514,7 @@
     gen_lock = snewn(wh, bool);
 
     do {
-	int *dsf = divvy_rectangle(w, h, k, rs);
+	DSF *dsf = divvy_rectangle(w, h, k, rs);
 
 	/*
 	 * Go through the dsf and find the indices of all the
--- a/unfinished/slide.c
+++ b/unfinished/slide.c
@@ -294,7 +294,7 @@
 			       bool *forcefield)
 {
     int wh = w*h;
-    int *dsf = snew_dsf(wh);
+    DSF *dsf = snew_dsf(wh);
     int i, x, y;
     int retpos, retlen = (w*2+2)*(h*2+1)+1;
     char *ret = snewn(retlen, char);
@@ -648,7 +648,7 @@
     unsigned char *board, *board2;
     bool *forcefield;
     bool *tried_merge;
-    int *dsf;
+    DSF *dsf;
     int *list, nlist, pos;
     int tx, ty;
     int i, j;
@@ -2083,7 +2083,7 @@
     draw_update(dr, tx, ty, TILESIZE, TILESIZE);
 }
 
-static unsigned long find_piecepart(int w, int h, int *dsf, int x, int y)
+static unsigned long find_piecepart(int w, int h, DSF *dsf, int x, int y)
 {
     int i = y*w+x;
     int canon = dsf_canonify(dsf, i);
@@ -2119,7 +2119,7 @@
 {
     int w = state->w, h = state->h, wh = w*h;
     unsigned char *board;
-    int *dsf;
+    DSF *dsf;
     int x, y, mainanchor, mainpos, dragpos, solvepos, solvesrc, solvedst;
 
     /*