mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Net: reference-count the barriers array.
Net is one of the very oldest puzzles in the collection, and has apparently been physically copying the complete collection of totally immutable barrier data in every game state since 2004. About time it stopped, I think!
This commit is contained in:
28
net.c
28
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 {
|
||||
|
Reference in New Issue
Block a user