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 */
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);
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;
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));
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);
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;
*/
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;
}
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) {
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) ||
#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;
};
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;
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') {
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;
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);
}
char buf[80];
char c, i;
- if (state->immutable[hy * w2 + hx])
+ if (state->common->immutable[hy * w2 + hx])
return NULL;
c = '-';
ret = dup_game(state);
i = y * w2 + x;
- if (state->immutable[i]) {
+ if (state->common->immutable[i]) {
free_game(ret);
return NULL;
}
tile |= flash;
- if (state->immutable[i])
+ if (state->common->immutable[i])
tile |= FF_IMMUTABLE;
if (ui->cursor && ui->cx == x && ui->cy == y)