mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-20 15:41:30 -07:00
Undead: you can now mark clues as done
This commit is contained in:

committed by
Simon Tatham

parent
c3285318e6
commit
f0750894ff
@ -17,3 +17,6 @@ press Backspace.
|
|||||||
Right-click in a square and then type a letter to add or remove the
|
Right-click in a square and then type a letter to add or remove the
|
||||||
monster as a pencil mark, indicating monsters that you think
|
monster as a pencil mark, indicating monsters that you think
|
||||||
<em>might</em> go in that square.
|
<em>might</em> go in that square.
|
||||||
|
<p>
|
||||||
|
Left-click on a clue to mark it as done (grey it out). To unmark a
|
||||||
|
clue as done, left-click on it again.
|
||||||
|
@ -3054,6 +3054,9 @@ If you prefer plain letters of the alphabet to cute monster pictures,
|
|||||||
you can press \q{A} to toggle between showing the monsters as monsters or
|
you can press \q{A} to toggle between showing the monsters as monsters or
|
||||||
showing them as letters.
|
showing them as letters.
|
||||||
|
|
||||||
|
Left-clicking a clue will mark it as done (grey it out), or unmark it
|
||||||
|
if it is already marked.
|
||||||
|
|
||||||
(All the actions described in \k{common-actions} are also available.)
|
(All the actions described in \k{common-actions} are also available.)
|
||||||
|
|
||||||
\H{undead-parameters} \I{parameters, for Undead}Undead parameters
|
\H{undead-parameters} \I{parameters, for Undead}Undead parameters
|
||||||
|
68
undead.c
68
undead.c
@ -49,6 +49,7 @@ enum {
|
|||||||
COL_GHOST,
|
COL_GHOST,
|
||||||
COL_ZOMBIE,
|
COL_ZOMBIE,
|
||||||
COL_VAMPIRE,
|
COL_VAMPIRE,
|
||||||
|
COL_DONE,
|
||||||
NCOLOURS
|
NCOLOURS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -237,6 +238,7 @@ struct game_state {
|
|||||||
unsigned char *pencils;
|
unsigned char *pencils;
|
||||||
unsigned char *cell_errors;
|
unsigned char *cell_errors;
|
||||||
unsigned char *hint_errors;
|
unsigned char *hint_errors;
|
||||||
|
unsigned char *hints_done;
|
||||||
unsigned char count_errors[3];
|
unsigned char count_errors[3];
|
||||||
int solved;
|
int solved;
|
||||||
int cheated;
|
int cheated;
|
||||||
@ -289,6 +291,9 @@ static game_state *new_state(const game_params *params) {
|
|||||||
state->hint_errors = snewn(2*state->common->num_paths, unsigned char);
|
state->hint_errors = snewn(2*state->common->num_paths, unsigned char);
|
||||||
for (i=0;i<2*state->common->num_paths;i++)
|
for (i=0;i<2*state->common->num_paths;i++)
|
||||||
state->hint_errors[i] = FALSE;
|
state->hint_errors[i] = FALSE;
|
||||||
|
state->hints_done = snewn(2 * state->common->num_paths, unsigned char);
|
||||||
|
memset(state->hints_done, 0,
|
||||||
|
2 * state->common->num_paths * sizeof(unsigned char));
|
||||||
for (i=0;i<3;i++)
|
for (i=0;i<3;i++)
|
||||||
state->count_errors[i] = FALSE;
|
state->count_errors[i] = FALSE;
|
||||||
|
|
||||||
@ -332,6 +337,13 @@ static game_state *dup_game(const game_state *state)
|
|||||||
}
|
}
|
||||||
else ret->hint_errors = NULL;
|
else ret->hint_errors = NULL;
|
||||||
|
|
||||||
|
if (state->hints_done != NULL) {
|
||||||
|
ret->hints_done = snewn(2 * state->common->num_paths, unsigned char);
|
||||||
|
memcpy(ret->hints_done, state->hints_done,
|
||||||
|
2 * state->common->num_paths * sizeof(unsigned char));
|
||||||
|
}
|
||||||
|
else ret->hints_done = NULL;
|
||||||
|
|
||||||
ret->count_errors[0] = state->count_errors[0];
|
ret->count_errors[0] = state->count_errors[0];
|
||||||
ret->count_errors[1] = state->count_errors[1];
|
ret->count_errors[1] = state->count_errors[1];
|
||||||
ret->count_errors[2] = state->count_errors[2];
|
ret->count_errors[2] = state->count_errors[2];
|
||||||
@ -358,6 +370,7 @@ static void free_game(game_state *state) {
|
|||||||
if (state->common->fixed != NULL) sfree(state->common->fixed);
|
if (state->common->fixed != NULL) sfree(state->common->fixed);
|
||||||
sfree(state->common);
|
sfree(state->common);
|
||||||
}
|
}
|
||||||
|
if (state->hints_done != NULL) sfree(state->hints_done);
|
||||||
if (state->hint_errors != NULL) sfree(state->hint_errors);
|
if (state->hint_errors != NULL) sfree(state->hint_errors);
|
||||||
if (state->cell_errors != NULL) sfree(state->cell_errors);
|
if (state->cell_errors != NULL) sfree(state->cell_errors);
|
||||||
if (state->pencils != NULL) sfree(state->pencils);
|
if (state->pencils != NULL) sfree(state->pencils);
|
||||||
@ -1662,12 +1675,40 @@ struct game_drawstate {
|
|||||||
unsigned char count_errors[3];
|
unsigned char count_errors[3];
|
||||||
unsigned char *cell_errors;
|
unsigned char *cell_errors;
|
||||||
unsigned char *hint_errors;
|
unsigned char *hint_errors;
|
||||||
|
unsigned char *hints_done;
|
||||||
|
|
||||||
int hx, hy, hshow, hpencil; /* as for game_ui. */
|
int hx, hy, hshow, hpencil; /* as for game_ui. */
|
||||||
int hflash;
|
int hflash;
|
||||||
int ascii;
|
int ascii;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int is_clue(const game_state *state, int x, int y)
|
||||||
|
{
|
||||||
|
int h = state->common->params.h, w = state->common->params.w;
|
||||||
|
|
||||||
|
if (((x == 0 || x == w + 1) && y > 0 && y <= h) ||
|
||||||
|
((y == 0 || y == h + 1) && x > 0 && x <= w))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clue_index(const game_state *state, int x, int y)
|
||||||
|
{
|
||||||
|
int h = state->common->params.h, w = state->common->params.w;
|
||||||
|
|
||||||
|
if (y == 0)
|
||||||
|
return x - 1;
|
||||||
|
else if (x == w + 1)
|
||||||
|
return w + y - 1;
|
||||||
|
else if (y == h + 1)
|
||||||
|
return 2 * w + h - x;
|
||||||
|
else if (x == 0)
|
||||||
|
return 2 * (w + h) - y;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#define TILESIZE (ds->tilesize)
|
#define TILESIZE (ds->tilesize)
|
||||||
#define BORDER (TILESIZE/4)
|
#define BORDER (TILESIZE/4)
|
||||||
|
|
||||||
@ -1818,6 +1859,11 @@ static char *interpret_move(const game_state *state, game_ui *ui,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (button == LEFT_BUTTON) {
|
||||||
|
if (is_clue(state, gx, gy)) {
|
||||||
|
sprintf(buf, "D%d,%d", gx, gy);
|
||||||
|
return dupstr(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1942,7 +1988,7 @@ int check_path_solution(game_state *state, int p) {
|
|||||||
|
|
||||||
static game_state *execute_move(const game_state *state, const char *move)
|
static game_state *execute_move(const game_state *state, const char *move)
|
||||||
{
|
{
|
||||||
int x,n,p,i;
|
int x,y,n,p,i;
|
||||||
char c;
|
char c;
|
||||||
int correct;
|
int correct;
|
||||||
int solver;
|
int solver;
|
||||||
@ -1969,6 +2015,11 @@ static game_state *execute_move(const game_state *state, const char *move)
|
|||||||
if (c == 'z') ret->pencils[x] ^= 4;
|
if (c == 'z') ret->pencils[x] ^= 4;
|
||||||
move += n;
|
move += n;
|
||||||
}
|
}
|
||||||
|
if (c == 'D' && sscanf(move + 1, "%d,%d%n", &x, &y, &n) == 2 &&
|
||||||
|
is_clue(ret, x, y)) {
|
||||||
|
ret->hints_done[clue_index(ret, x, y)] ^= 1;
|
||||||
|
move += n + 1;
|
||||||
|
}
|
||||||
if (*move == ';') move++;
|
if (*move == ';') move++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2058,6 +2109,10 @@ static float *game_colours(frontend *fe, int *ncolours)
|
|||||||
ret[COL_VAMPIRE * 3 + 1] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
|
ret[COL_VAMPIRE * 3 + 1] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
|
||||||
ret[COL_VAMPIRE * 3 + 2] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
|
ret[COL_VAMPIRE * 3 + 2] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
|
||||||
|
|
||||||
|
ret[COL_DONE * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] / 1.5F;
|
||||||
|
ret[COL_DONE * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] / 1.5F;
|
||||||
|
ret[COL_DONE * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] / 1.5F;
|
||||||
|
|
||||||
*ncolours = NCOLOURS;
|
*ncolours = NCOLOURS;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2090,6 +2145,9 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
|
|||||||
ds->hint_errors = snewn(2*state->common->num_paths,unsigned char);
|
ds->hint_errors = snewn(2*state->common->num_paths,unsigned char);
|
||||||
for (i=0;i<2*state->common->num_paths;i++)
|
for (i=0;i<2*state->common->num_paths;i++)
|
||||||
ds->hint_errors[i] = FALSE;
|
ds->hint_errors[i] = FALSE;
|
||||||
|
ds->hints_done = snewn(2 * state->common->num_paths, unsigned char);
|
||||||
|
memset(ds->hints_done, 0,
|
||||||
|
2 * state->common->num_paths * sizeof(unsigned char));
|
||||||
|
|
||||||
ds->hshow = ds->hpencil = ds->hflash = 0;
|
ds->hshow = ds->hpencil = ds->hflash = 0;
|
||||||
ds->hx = ds->hy = 0;
|
ds->hx = ds->hy = 0;
|
||||||
@ -2097,6 +2155,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void game_free_drawstate(drawing *dr, game_drawstate *ds) {
|
static void game_free_drawstate(drawing *dr, game_drawstate *ds) {
|
||||||
|
sfree(ds->hints_done);
|
||||||
sfree(ds->hint_errors);
|
sfree(ds->hint_errors);
|
||||||
sfree(ds->cell_errors);
|
sfree(ds->cell_errors);
|
||||||
sfree(ds->pencils);
|
sfree(ds->pencils);
|
||||||
@ -2325,6 +2384,8 @@ static void draw_path_hint(drawing *dr, game_drawstate *ds,
|
|||||||
color = COL_ERROR;
|
color = COL_ERROR;
|
||||||
else if (hflash)
|
else if (hflash)
|
||||||
color = COL_FLASH;
|
color = COL_FLASH;
|
||||||
|
else if (ds->hints_done[hint_index])
|
||||||
|
color = COL_DONE;
|
||||||
else
|
else
|
||||||
color = COL_TEXT;
|
color = COL_TEXT;
|
||||||
|
|
||||||
@ -2453,6 +2514,11 @@ static int is_hint_stale(const game_drawstate *ds, int hflash,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ds->hints_done[index] != state->hints_done[index]) {
|
||||||
|
ds->hints_done[index] = state->hints_done[index];
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user