aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/net.c b/net.c
index 57d91d3..cece21d 100644
--- a/net.c
+++ b/net.c
@@ -102,12 +102,17 @@ struct game_params {
float barrier_probability;
};
+typedef struct game_immutable_state {
+ int refcount;
+ unsigned char *barriers;
+} game_immutable_state;
+
struct game_state {
int width, height, wrapping, completed;
int last_rotate_x, last_rotate_y, last_rotate_dir;
int used_solve;
unsigned char *tiles;
- unsigned char *barriers;
+ struct game_immutable_state *imm;
};
#define OFFSETWH(x2,y2,x1,y1,dir,width,height) \
@@ -119,7 +124,7 @@ struct game_state {
#define index(state, a, x, y) ( a[(y) * (state)->width + (x)] )
#define tile(state, x, y) index(state, (state)->tiles, x, y)
-#define barrier(state, x, y) index(state, (state)->barriers, x, y)
+#define barrier(state, x, y) index(state, (state)->imm->barriers, x, y)
struct xyd {
int x, y, direction;
@@ -1653,12 +1658,14 @@ static game_state *new_game(midend *me, const game_params *params,
w = state->width = params->width;
h = state->height = params->height;
state->wrapping = params->wrapping;
+ state->imm = snew(game_immutable_state);
+ state->imm->refcount = 1;
state->last_rotate_dir = state->last_rotate_x = state->last_rotate_y = 0;
state->completed = state->used_solve = FALSE;
state->tiles = snewn(state->width * state->height, unsigned char);
memset(state->tiles, 0, state->width * state->height);
- state->barriers = snewn(state->width * state->height, unsigned char);
- memset(state->barriers, 0, state->width * state->height);
+ state->imm->barriers = snewn(state->width * state->height, unsigned char);
+ memset(state->imm->barriers, 0, state->width * state->height);
/*
* Parse the game description into the grid.
@@ -1729,6 +1736,8 @@ static game_state *dup_game(const game_state *state)
game_state *ret;
ret = snew(game_state);
+ ret->imm = state->imm;
+ ret->imm->refcount++;
ret->width = state->width;
ret->height = state->height;
ret->wrapping = state->wrapping;
@@ -1739,16 +1748,17 @@ static game_state *dup_game(const game_state *state)
ret->last_rotate_y = state->last_rotate_y;
ret->tiles = snewn(state->width * state->height, unsigned char);
memcpy(ret->tiles, state->tiles, state->width * state->height);
- ret->barriers = snewn(state->width * state->height, unsigned char);
- memcpy(ret->barriers, state->barriers, state->width * state->height);
return ret;
}
static void free_game(game_state *state)
{
+ if (--state->imm->refcount == 0) {
+ sfree(state->imm->barriers);
+ sfree(state->imm);
+ }
sfree(state->tiles);
- sfree(state->barriers);
sfree(state);
}
@@ -1771,7 +1781,7 @@ static char *solve_game(const game_state *state, const game_state *currstate,
memcpy(tiles, state->tiles, state->width * state->height);
solver_result = net_solver(state->width, state->height, tiles,
- state->barriers, state->wrapping);
+ state->imm->barriers, state->wrapping);
if (solver_result < 0) {
*error = "No solution exists for this puzzle";
@@ -2004,7 +2014,7 @@ static int *compute_loops_inner(int w, int h, int wrapping,
static int *compute_loops(const game_state *state)
{
return compute_loops_inner(state->width, state->height, state->wrapping,
- state->tiles, state->barriers);
+ state->tiles, state->imm->barriers);
}
struct game_ui {