sfree(params);
}
-static game_params *dup_params(game_params *params) {
+static game_params *dup_params(const game_params *params)
+{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
return ret;
return;
}
-static char *encode_params(game_params *params, int full) {
+static char *encode_params(const game_params *params, int full)
+{
char buf[256];
sprintf(buf, "%dx%d", params->w, params->h);
if (full)
return dupstr(buf);
}
-static config_item *game_configure(game_params *params) {
+static config_item *game_configure(const game_params *params)
+{
config_item *ret;
char buf[64];
return ret;
}
-static game_params *custom_params(config_item *cfg) {
+static game_params *custom_params(const config_item *cfg)
+{
game_params *ret = snew(game_params);
ret->w = atoi(cfg[0].sval);
return ret;
}
-static char *validate_params(game_params *params, int full) {
+static char *validate_params(const game_params *params, int full)
+{
if ((params->w * params->h ) > 54) return "Grid is too big";
if (params->w < 3) return "Width must be at least 3";
if (params->h < 3) return "Height must be at least 3";
int cheated;
};
-static game_state *new_state(game_params *params) {
+static game_state *new_state(const game_params *params) {
int i;
game_state *state = snew(game_state);
state->common = snew(struct game_common);
return state;
}
-static game_state *dup_game(game_state *state) {
+static game_state *dup_game(const game_state *state)
+{
game_state *ret = snew(game_state);
ret->common = state->common;
void get_unique(game_state *state, int counter, random_state *rs) {
- int p,i,c,count_uniques;
+ int p,i,c,pathlimit,count_uniques;
struct guess path_guess;
+ int *view_count;
struct entry {
struct entry *link;
struct {
struct entry *head;
struct entry *node;
- } views, single_views, loop_views, test_views;
+ } views, single_views, test_views;
struct entry test_entry;
-
+
path_guess.length = state->common->paths[counter].num_monsters;
path_guess.guess = snewn(path_guess.length,int);
path_guess.possible = snewn(path_guess.length,int);
views.head = NULL;
views.node = NULL;
+
+ pathlimit = state->common->paths[counter].length + 1;
+ view_count = snewn(pathlimit*pathlimit, int);
+ for (i = 0; i < pathlimit*pathlimit; i++)
+ view_count[i] = 0;
do {
- int mirror;
+ int mirror, start_view, end_view;
- views.node = snewn(1,struct entry);
- views.node->link = views.head;
- views.node->guess = snewn(path_guess.length,int);
- views.head = views.node;
- views.node->start_view = 0;
- views.node->end_view = 0;
- memcpy(views.node->guess, path_guess.guess,
- path_guess.length*sizeof(int));
-
mirror = FALSE;
+ start_view = 0;
for (p=0;p<state->common->paths[counter].length;p++) {
if (state->common->paths[counter].p[p] == -1) mirror = TRUE;
else {
if (state->common->paths[counter].p[p] ==
state->common->paths[counter].mapping[i]) {
if (path_guess.guess[i] == 1 && mirror == TRUE)
- views.node->start_view++;
+ start_view++;
if (path_guess.guess[i] == 2 && mirror == FALSE)
- views.node->start_view++;
+ start_view++;
if (path_guess.guess[i] == 4)
- views.node->start_view++;
+ start_view++;
break;
}
}
}
}
mirror = FALSE;
+ end_view = 0;
for (p=state->common->paths[counter].length-1;p>=0;p--) {
if (state->common->paths[counter].p[p] == -1) mirror = TRUE;
else {
if (state->common->paths[counter].p[p] ==
state->common->paths[counter].mapping[i]) {
if (path_guess.guess[i] == 1 && mirror == TRUE)
- views.node->end_view++;
+ end_view++;
if (path_guess.guess[i] == 2 && mirror == FALSE)
- views.node->end_view++;
+ end_view++;
if (path_guess.guess[i] == 4)
- views.node->end_view++;
+ end_view++;
break;
}
}
}
}
+
+ assert(start_view >= 0 && start_view < pathlimit);
+ assert(end_view >= 0 && end_view < pathlimit);
+ i = start_view * pathlimit + end_view;
+ view_count[i]++;
+ if (view_count[i] == 1) {
+ views.node = snewn(1,struct entry);
+ views.node->link = views.head;
+ views.node->guess = snewn(path_guess.length,int);
+ views.head = views.node;
+ views.node->start_view = start_view;
+ views.node->end_view = end_view;
+ memcpy(views.node->guess, path_guess.guess,
+ path_guess.length*sizeof(int));
+ }
} while (next_list(&path_guess, path_guess.length-1));
/* extract single entries from view list */
while (test_views.head != NULL) {
test_views.node = test_views.head;
test_views.head = test_views.head->link;
- c = 0;
- loop_views.head = views.head;
- loop_views.node = views.node;
- while (loop_views.head != NULL) {
- loop_views.node = loop_views.head;
- loop_views.head = loop_views.head->link;
- if (test_views.node->start_view == loop_views.node->start_view &&
- test_views.node->end_view == loop_views.node->end_view)
- c++;
- }
- if (c == 1) {
+ i = test_views.node->start_view * pathlimit + test_views.node->end_view;
+ if (view_count[i] == 1) {
single_views.node = snewn(1,struct entry);
single_views.node->link = single_views.head;
single_views.node->guess = snewn(path_guess.length,int);
}
}
+ sfree(view_count);
+
if (count_uniques > 0) {
test_entry.start_view = 0;
test_entry.end_view = 0;
return pa->num_monsters - pb->num_monsters;
}
-static char *new_game_desc(game_params *params, random_state *rs,
+static char *new_game_desc(const game_params *params, random_state *rs,
char **aux, int interactive) {
int i,count,c,w,h,r,p,g;
game_state *new;
return;
}
-static game_state *new_game(midend *me, game_params *params, char *desc) {
+static game_state *new_game(midend *me, const game_params *params,
+ const char *desc)
+{
int i;
int n;
int count;
return state;
}
-static char *validate_desc(game_params *params, char *desc) {
+static char *validate_desc(const game_params *params, const char *desc)
+{
int i;
int w = params->w, h = params->h;
int wh = w*h;
int area;
int monsters;
int monster_count;
- char *desc_s = desc;
+ const char *desc_s = desc;
for (i=0;i<3;i++) {
if (!*desc) return "Faulty game description";
return NULL;
}
-static char *solve_game(game_state *state_start, game_state *currstate, char *aux, char **error) {
+static char *solve_game(const game_state *state_start, const game_state *currstate,
+ const char *aux, char **error)
+{
int p;
int *old_guess;
int iterative_depth;
return move;
}
-static int game_can_format_as_text_now(game_params *params) {
+static int game_can_format_as_text_now(const game_params *params)
+{
return TRUE;
}
-static char *game_text_format(game_state *state) {
+static char *game_text_format(const game_state *state)
+{
int w,h,c,r,xi,g;
char *ret;
char buf[120];
int ascii;
};
-static game_ui *new_ui(game_state *state) {
+static game_ui *new_ui(const game_state *state)
+{
game_ui *ui = snew(game_ui);
ui->hx = ui->hy = 0;
ui->hpencil = ui->hshow = ui->hcursor = 0;
return;
}
-static char *encode_ui(game_ui *ui) {
+static char *encode_ui(const game_ui *ui)
+{
return NULL;
}
-static void decode_ui(game_ui *ui, char *encoding) {
+static void decode_ui(game_ui *ui, const char *encoding)
+{
return;
}
-static void game_changed_state(game_ui *ui, game_state *oldstate, game_state *newstate) {
+static void game_changed_state(game_ui *ui, const game_state *oldstate,
+ const game_state *newstate)
+{
/* See solo.c; if we were pencil-mode highlighting and
* somehow a square has just been properly filled, cancel
* pencil mode. */
#define TILESIZE (ds->tilesize)
#define BORDER (TILESIZE/4)
-static char *interpret_move(game_state *state, game_ui *ui,
- const game_drawstate *ds, int x, int y, int button)
+static char *interpret_move(const game_state *state, game_ui *ui,
+ const game_drawstate *ds,
+ int x, int y, int button)
{
int gx,gy;
int g,xi;
return correct;
}
-static game_state *execute_move(game_state *state, char *move) {
+static game_state *execute_move(const game_state *state, const char *move)
+{
int x,n,p,i;
char c;
int correct;
#define PREFERRED_TILE_SIZE 64
-static void game_compute_size(game_params *params, int tilesize,
- int *x, int *y) {
+static void game_compute_size(const game_params *params, int tilesize,
+ int *x, int *y)
+{
/* Ick: fake up `ds->tilesize' for macro expansion purposes */
struct { int tilesize; } ads, *ds = &ads;
ads.tilesize = tilesize;
}
static void game_set_size(drawing *dr, game_drawstate *ds,
- game_params *params, int tilesize) {
+ const game_params *params, int tilesize)
+{
ds->tilesize = tilesize;
return;
}
#define COLOUR(ret, i, r, g, b) ((ret[3*(i)+0] = (r)), (ret[3*(i)+1] = (g)), (ret[3*(i)+2] = (b)))
-static float *game_colours(frontend *fe, int *ncolours) {
+static float *game_colours(frontend *fe, int *ncolours)
+{
float *ret = snewn(3 * NCOLOURS, float);
frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
return ret;
}
-static game_drawstate *game_new_drawstate(drawing *dr, game_state *state) {
+static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
+{
int i;
struct game_drawstate *ds = snew(struct game_drawstate);
}
static void draw_cell_background(drawing *dr, game_drawstate *ds,
- game_state *state, game_ui *ui, int x, int y) {
+ const game_state *state, const game_ui *ui,
+ int x, int y) {
int hon;
int dx,dy;
}
static void draw_monster_count(drawing *dr, game_drawstate *ds,
- game_state *state, int c, int hflash) {
- int dx,dy,dh;
+ const game_state *state, int c, int hflash) {
+ int dx,dy;
char buf[8];
char bufm[8];
- dy = TILESIZE/2;
- dh = TILESIZE;
+ dy = TILESIZE/4;
dx = BORDER+(ds->w+2)*TILESIZE/2+TILESIZE/4;
switch (c) {
case 0:
break;
}
+ draw_rect(dr, dx-2*TILESIZE/3, dy, 3*TILESIZE/2, TILESIZE,
+ COL_BACKGROUND);
if (!ds->ascii) {
- draw_rect(dr,dx-2*TILESIZE/3,dy,3*TILESIZE/2,dh,COL_BACKGROUND);
- draw_monster(dr,ds,dx-TILESIZE/3,dh,2*TILESIZE/3,hflash,1<<c);
- draw_text(dr,dx,dh,FONT_VARIABLE,dy-1,ALIGN_HLEFT|ALIGN_VCENTRE,
- (state->count_errors[c] ? COL_ERROR : hflash ? COL_FLASH : COL_TEXT), buf);
- draw_update(dr,dx-2*TILESIZE/3,dy,3*TILESIZE/2,dh);
- }
- else {
- draw_rect(dr,dx-2*TILESIZE/3,dy,3*TILESIZE/2,dh,COL_BACKGROUND);
- draw_text(dr,dx-TILESIZE/3,dh,FONT_VARIABLE,dy-1,
+ draw_monster(dr, ds, dx-TILESIZE/3, dy+TILESIZE/2,
+ 2*TILESIZE/3, hflash, 1<<c);
+ } else {
+ draw_text(dr, dx-TILESIZE/3,dy+TILESIZE/2,FONT_VARIABLE,TILESIZE/2,
ALIGN_HCENTRE|ALIGN_VCENTRE,
hflash ? COL_FLASH : COL_TEXT, bufm);
- draw_text(dr,dx,dh,FONT_VARIABLE,dy-1,ALIGN_HLEFT|ALIGN_VCENTRE,
- (state->count_errors[c] ? COL_ERROR : hflash ? COL_FLASH : COL_TEXT), buf);
- draw_update(dr,dx-2*TILESIZE/3,dy,3*TILESIZE/2,dh);
}
+ draw_text(dr, dx, dy+TILESIZE/2, FONT_VARIABLE, TILESIZE/2,
+ ALIGN_HLEFT|ALIGN_VCENTRE,
+ (state->count_errors[c] ? COL_ERROR :
+ hflash ? COL_FLASH : COL_TEXT), buf);
+ draw_update(dr, dx-2*TILESIZE/3, dy, 3*TILESIZE/2, TILESIZE);
return;
}
-static void draw_path_hint(drawing *dr, game_drawstate *ds, game_state *state,
+static void draw_path_hint(drawing *dr, game_drawstate *ds,
+ const game_state *state,
int i, int hflash, int start) {
int dx,dy,x,y;
int p,error;
return;
}
-static void draw_mirror(drawing *dr, game_drawstate *ds, game_state *state,
- int x, int y, int hflash, int mirror) {
+static void draw_mirror(drawing *dr, game_drawstate *ds,
+ const game_state *state, int x, int y,
+ int hflash, int mirror) {
int dx,dy,mx1,my1,mx2,my2;
dx = BORDER+(x* ds->tilesize)+(TILESIZE/2);
dy = BORDER+(y* ds->tilesize)+(TILESIZE/2)+TILESIZE;
return;
}
-static void draw_big_monster(drawing *dr, game_drawstate *ds, game_state *state,
- int x, int y, int hflash, int monster)
+static void draw_big_monster(drawing *dr, game_drawstate *ds,
+ const game_state *state, int x, int y,
+ int hflash, int monster)
{
int dx,dy;
char buf[10];
return;
}
-static void draw_pencils(drawing *dr, game_drawstate *ds, game_state *state,
- int x, int y, int pencil) {
+static void draw_pencils(drawing *dr, game_drawstate *ds,
+ const game_state *state, int x, int y, int pencil)
+{
int dx, dy;
int monsters[4];
int i, j, px, py;
#define FLASH_TIME 0.7F
-static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
- game_state *state, int dir, game_ui *ui,
- float animtime, float flashtime) {
+static void game_redraw(drawing *dr, game_drawstate *ds,
+ const game_state *oldstate, const game_state *state,
+ int dir, const game_ui *ui,
+ float animtime, float flashtime)
+{
int i,j,x,y,xy;
int stale, xi, c, hflash, hchanged, changed_ascii;
return;
}
-static float game_anim_length(game_state *oldstate, game_state *newstate,
- int dir, game_ui *ui) {
+static float game_anim_length(const game_state *oldstate,
+ const game_state *newstate, int dir, game_ui *ui)
+{
return 0.0F;
}
-static float game_flash_length(game_state *oldstate, game_state *newstate,
- int dir, game_ui *ui) {
+static float game_flash_length(const game_state *oldstate,
+ const game_state *newstate, int dir, game_ui *ui)
+{
return (!oldstate->solved && newstate->solved && !oldstate->cheated &&
!newstate->cheated) ? FLASH_TIME : 0.0F;
}
-static int game_status(game_state *state) {
+static int game_status(const game_state *state)
+{
return state->solved;
}
-static int game_timing_state(game_state *state, game_ui *ui) {
+static int game_timing_state(const game_state *state, game_ui *ui)
+{
return TRUE;
}
-static void game_print_size(game_params *params, float *x, float *y) {
+static void game_print_size(const game_params *params, float *x, float *y)
+{
}
-static void game_print(drawing *dr, game_state *state, int tilesize) {
+static void game_print(drawing *dr, const game_state *state, int tilesize)
+{
}
#ifdef COMBINED