aboutsummaryrefslogtreecommitdiff
path: root/dominosa.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2023-04-20 13:13:47 +0100
committerSimon Tatham <anakin@pobox.com>2023-04-20 14:28:22 +0100
commit16f997d34c7b435d3fcf5774c700579e188b017f (patch)
tree952e854fdaf51a53996a7e39e821669633a486ac /dominosa.c
parent6c02b72d766fcb6a9598bdde80294a41e53cd02c (diff)
downloadpuzzles-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 'dominosa.c')
-rw-r--r--dominosa.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/dominosa.c b/dominosa.c
index eba9465..7a87e4b 100644
--- a/dominosa.c
+++ b/dominosa.c
@@ -350,7 +350,7 @@ struct solver_scratch {
struct solver_square **squares_by_number;
struct findloopstate *fls;
bool squares_by_number_initialised;
- int *wh_scratch, *pc_scratch, *pc_scratch2, *dc_scratch;
+ int *wh_scratch, *pc_scratch, *pc_scratch2, *dc_scratch, *dsf_scratch;
};
static struct solver_scratch *solver_make_scratch(int n)
@@ -482,6 +482,7 @@ static struct solver_scratch *solver_make_scratch(int n)
sc->wh_scratch = NULL;
sc->pc_scratch = sc->pc_scratch2 = NULL;
sc->dc_scratch = NULL;
+ sc->dsf_scratch = NULL;
return sc;
}
@@ -509,6 +510,7 @@ static void solver_free_scratch(struct solver_scratch *sc)
sfree(sc->pc_scratch);
sfree(sc->pc_scratch2);
sfree(sc->dc_scratch);
+ sfree(sc->dsf_scratch);
sfree(sc);
}
@@ -1425,19 +1427,21 @@ static bool deduce_forcing_chain(struct solver_scratch *sc)
sc->pc_scratch2 = snewn(sc->pc, int);
if (!sc->dc_scratch)
sc->dc_scratch = snewn(sc->dc, int);
+ if (!sc->dsf_scratch)
+ sc->dsf_scratch = snew_dsf(sc->pc);
/*
* Start by identifying chains of placements which must all occur
* together if any of them occurs. We do this by making
- * pc_scratch2 an edsf binding the placements into an equivalence
+ * dsf_scratch an edsf binding the placements into an equivalence
* class for each entire forcing chain, with the two possible sets
* of dominoes for the chain listed as inverses.
*/
- dsf_init(sc->pc_scratch2, sc->pc);
+ dsf_init(sc->dsf_scratch, sc->pc);
for (si = 0; si < sc->wh; si++) {
struct solver_square *sq = &sc->squares[si];
if (sq->nplacements == 2)
- edsf_merge(sc->pc_scratch2,
+ edsf_merge(sc->dsf_scratch,
sq->placements[0]->index,
sq->placements[1]->index, true);
}
@@ -1452,7 +1456,7 @@ static bool deduce_forcing_chain(struct solver_scratch *sc)
*/
for (pi = 0; pi < sc->pc; pi++) {
bool inv;
- int c = edsf_canonify(sc->pc_scratch2, pi, &inv);
+ int c = edsf_canonify(sc->dsf_scratch, pi, &inv);
sc->pc_scratch[pi] = c * 2 + (inv ? 1 : 0);
}