diff options
| author | Simon Tatham <anakin@pobox.com> | 2023-04-20 13:13:47 +0100 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 2023-04-20 14:28:22 +0100 |
| commit | 16f997d34c7b435d3fcf5774c700579e188b017f (patch) | |
| tree | 952e854fdaf51a53996a7e39e821669633a486ac /map.c | |
| parent | 6c02b72d766fcb6a9598bdde80294a41e53cd02c (diff) | |
| download | puzzles-16f997d34c7b435d3fcf5774c700579e188b017f.zip puzzles-16f997d34c7b435d3fcf5774c700579e188b017f.tar.gz puzzles-16f997d34c7b435d3fcf5774c700579e188b017f.tar.bz2 puzzles-16f997d34c7b435d3fcf5774c700579e188b017f.tar.xz | |
Stop putting dsfs in existing scratch int arrays.
I'm going to work towards turning 'dsf' into an opaque type, so that I
can improve its implementation without breaking clients. The first
step is to deal manually with puzzles that currently reuse a single
array of ints for multiple purposes, some of which are dsf and some
are not.
In divvy_rectangle_attempt, 'tmp' was used as an int array and later a
dsf, and I've made a new 'tmpdsf' to be the latter.
In Dominosa, solver->pc_scratch2 was sometimes a dsf, and now there's
a new solver->dsf_scratch.
In Map, parse_edge_list() needed a dsf internally and then never
exported it; it expected to be passed an array of 2*w*h ints and used
the second half as a dsf. Now it expects only w*h ints, and allocates
its own dsf internally, freeing it again before returning.
And in Tents, find_errors() was allocating a single block of 2*w*h
ints and using the second half of it as a dsf, apparently just to save
one malloc. Now we malloc and free the dsf separately.
Diffstat (limited to 'map.c')
| -rw-r--r-- | map.c | 39 |
1 files changed, 25 insertions, 14 deletions
@@ -1724,8 +1724,8 @@ static const char *parse_edge_list(const game_params *params, int i, k, pos; bool state; const char *p = *desc; - - dsf_init(map+wh, wh); + const char *err = NULL; + int *dsf = snew_dsf(wh); pos = -1; state = false; @@ -1736,8 +1736,10 @@ static const char *parse_edge_list(const game_params *params, * pairs of squares whenever the edge list shows a non-edge). */ while (*p && *p != ',') { - if (*p < 'a' || *p > 'z') - return "Unexpected character in edge list"; + if (*p < 'a' || *p > 'z') { + err = "Unexpected character in edge list"; + goto out; + } if (*p == 'z') k = 25; else @@ -1760,10 +1762,12 @@ static const char *parse_edge_list(const game_params *params, y = (pos - w*(h-1)) % h; dx = 1; dy = 0; - } else - return "Too much data in edge list"; + } else { + err = "Too much data in edge list"; + goto out; + } if (!state) - dsf_merge(map+wh, y*w+x, (y+dy)*w+(x+dx)); + dsf_merge(dsf, y*w+x, (y+dy)*w+(x+dx)); pos++; } @@ -1772,8 +1776,10 @@ static const char *parse_edge_list(const game_params *params, p++; } assert(pos <= 2*wh-w-h); - if (pos < 2*wh-w-h) - return "Too little data in edge list"; + if (pos < 2*wh-w-h) { + err = "Too little data in edge list"; + goto out; + } /* * Now go through again and allocate region numbers. @@ -1782,17 +1788,22 @@ static const char *parse_edge_list(const game_params *params, for (i = 0; i < wh; i++) map[i] = -1; for (i = 0; i < wh; i++) { - k = dsf_canonify(map+wh, i); + k = dsf_canonify(dsf, i); if (map[k] < 0) map[k] = pos++; map[i] = map[k]; } - if (pos != n) - return "Edge list defines the wrong number of regions"; + if (pos != n) { + err = "Edge list defines the wrong number of regions"; + goto out; + } *desc = p; + err = NULL; /* no error */ - return NULL; + out: + sfree(dsf); + return err; } static const char *validate_desc(const game_params *params, const char *desc) @@ -1802,7 +1813,7 @@ static const char *validate_desc(const game_params *params, const char *desc) int *map; const char *ret; - map = snewn(2*wh, int); + map = snewn(wh, int); ret = parse_edge_list(params, &desc, map); sfree(map); if (ret) |