diff options
| author | Simon Tatham <anakin@pobox.com> | 2018-11-13 21:58:14 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 2018-11-13 21:58:14 +0000 |
| commit | 47cec547e59ac8c5012f6091394dcb4304d64fc3 (patch) | |
| tree | 3eecd1216dd8562ec4285fb8f137a0e9773c550f /unfinished | |
| parent | cdc0563123951822b2f5f514336f8890ee6df522 (diff) | |
| download | puzzles-47cec547e59ac8c5012f6091394dcb4304d64fc3.zip puzzles-47cec547e59ac8c5012f6091394dcb4304d64fc3.tar.gz puzzles-47cec547e59ac8c5012f6091394dcb4304d64fc3.tar.bz2 puzzles-47cec547e59ac8c5012f6091394dcb4304d64fc3.tar.xz | |
Unruly, Group: reference-count the 'immutable' array.
I noticed this during the bool trawl: both of these games have an
array of flags indicating which grid squares are immutable starting
clues, and copy it in every call to dup_game, which is completely
unnecessary because it doesn't change during play. So now each one
lives in a reference-counted structure, as per my usual practice in
similar cases elsewhere.
Diffstat (limited to 'unfinished')
| -rw-r--r-- | unfinished/group.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/unfinished/group.c b/unfinished/group.c index e5aa81f..ef7ffba 100644 --- a/unfinished/group.c +++ b/unfinished/group.c @@ -82,11 +82,16 @@ struct game_params { bool id; }; +typedef struct group_common { + int refcount; + bool *immutable; +} group_common; + struct game_state { game_params par; digit *grid; - bool *immutable; int *pencil; /* bitmaps using bits 1<<1..1<<n */ + group_common *common; bool completed, cheated; digit *sequence; /* sequence of group elements shown */ @@ -850,11 +855,13 @@ static game_state *new_game(midend *me, const game_params *params, state->par = *params; /* structure copy */ state->grid = snewn(a, digit); - state->immutable = snewn(a, bool); + state->common = snew(group_common); + state->common->refcount = 1; + state->common->immutable = snewn(a, bool); state->pencil = snewn(a, int); for (i = 0; i < a; i++) { state->grid[i] = 0; - state->immutable[i] = false; + state->common->immutable[i] = false; state->pencil[i] = 0; } state->sequence = snewn(w, digit); @@ -867,7 +874,7 @@ static game_state *new_game(midend *me, const game_params *params, desc = spec_to_grid(desc, state->grid, a); for (i = 0; i < a; i++) if (state->grid[i] != 0) - state->immutable[i] = true; + state->common->immutable[i] = true; state->completed = false; state->cheated = false; @@ -883,12 +890,12 @@ static game_state *dup_game(const game_state *state) ret->par = state->par; /* structure copy */ ret->grid = snewn(a, digit); - ret->immutable = snewn(a, bool); + ret->common = state->common; + ret->common->refcount++; ret->pencil = snewn(a, int); ret->sequence = snewn(w, digit); ret->dividers = snewn(w, int); memcpy(ret->grid, state->grid, a*sizeof(digit)); - memcpy(ret->immutable, state->immutable, a*sizeof(bool)); memcpy(ret->pencil, state->pencil, a*sizeof(int)); memcpy(ret->sequence, state->sequence, w*sizeof(digit)); memcpy(ret->dividers, state->dividers, w*sizeof(int)); @@ -902,7 +909,10 @@ static game_state *dup_game(const game_state *state) static void free_game(game_state *state) { sfree(state->grid); - sfree(state->immutable); + if (--state->common->refcount == 0) { + sfree(state->common->immutable); + sfree(state->common); + } sfree(state->pencil); sfree(state->sequence); sfree(state); @@ -1318,7 +1328,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, ui->ohy = oty; ui->odx = ui->ody = 0; ui->odn = 1; - ui->hshow = !state->immutable[ty*w+tx]; + ui->hshow = !state->common->immutable[ty*w+tx]; ui->hpencil = false; } ui->hcursor = false; @@ -1423,7 +1433,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, */ if (!ui->hpencil && state->grid[index] == n) /* OK even if it is immutable */; - else if (state->immutable[index]) + else if (state->common->immutable[index]) return NULL; } @@ -1487,7 +1497,8 @@ static game_state *execute_move(const game_state *from, const char *move) free_game(ret); return NULL; } - if (from->immutable[y*w+x] && !(!pencil && from->grid[y*w+x] == n)) + if (from->common->immutable[y*w+x] && + !(!pencil && from->grid[y*w+x] == n)) return NULL; if (move[0] == 'P' && n > 0) { @@ -1900,7 +1911,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, else pencil = (long)state->pencil[sy*w+sx]; - if (state->immutable[sy*w+sx]) + if (state->common->immutable[sy*w+sx]) tile |= DF_IMMUTABLE; if ((ui->drag == 5 && ui->dragnum == sy) || |