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 /unruly.c | |
| 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 'unruly.c')
| -rw-r--r-- | unruly.c | 31 |
1 files changed, 21 insertions, 10 deletions
@@ -133,11 +133,16 @@ enum { #define FF_FLASH2 0x0800 #define FF_IMMUTABLE 0x1000 +typedef struct unruly_common { + int refcount; + bool *immutable; +} unruly_common; + struct game_state { int w2, h2; bool unique; char *grid; - bool *immutable; + unruly_common *common; bool completed, cheated; }; @@ -353,10 +358,12 @@ static game_state *blank_state(int w2, int h2, bool unique) state->h2 = h2; state->unique = unique; state->grid = snewn(s, char); - state->immutable = snewn(s, bool); + state->common = snew(unruly_common); + state->common->refcount = 1; + state->common->immutable = snewn(s, bool); memset(state->grid, EMPTY, s); - memset(state->immutable, 0, s*sizeof(bool)); + memset(state->common->immutable, 0, s*sizeof(bool)); state->completed = state->cheated = false; @@ -379,14 +386,14 @@ static game_state *new_game(midend *me, const game_params *params, pos += (*p - 'a'); if (pos < s) { state->grid[pos] = N_ZERO; - state->immutable[pos] = true; + state->common->immutable[pos] = true; } pos++; } else if (*p >= 'A' && *p < 'Z') { pos += (*p - 'A'); if (pos < s) { state->grid[pos] = N_ONE; - state->immutable[pos] = true; + state->common->immutable[pos] = true; } pos++; } else if (*p == 'Z' || *p == 'z') { @@ -409,7 +416,8 @@ static game_state *dup_game(const game_state *state) game_state *ret = blank_state(w2, h2, state->unique); memcpy(ret->grid, state->grid, s); - memcpy(ret->immutable, state->immutable, s*sizeof(bool)); + ret->common = state->common; + ret->common->refcount++; ret->completed = state->completed; ret->cheated = state->cheated; @@ -420,7 +428,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); } @@ -1539,7 +1550,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, char buf[80]; char c, i; - if (state->immutable[hy * w2 + hx]) + if (state->common->immutable[hy * w2 + hx]) return NULL; c = '-'; @@ -1604,7 +1615,7 @@ static game_state *execute_move(const game_state *state, const char *move) ret = dup_game(state); i = y * w2 + x; - if (state->immutable[i]) { + if (state->common->immutable[i]) { free_game(ret); return NULL; } @@ -1820,7 +1831,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, tile |= flash; - if (state->immutable[i]) + if (state->common->immutable[i]) tile |= FF_IMMUTABLE; if (ui->cursor && ui->cx == x && ui->cy == y) |