mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-20 07:31: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
|
||||
monster as a pencil mark, indicating monsters that you think
|
||||
<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
|
||||
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.)
|
||||
|
||||
\H{undead-parameters} \I{parameters, for Undead}Undead parameters
|
||||
|
68
undead.c
68
undead.c
@ -49,6 +49,7 @@ enum {
|
||||
COL_GHOST,
|
||||
COL_ZOMBIE,
|
||||
COL_VAMPIRE,
|
||||
COL_DONE,
|
||||
NCOLOURS
|
||||
};
|
||||
|
||||
@ -237,6 +238,7 @@ struct game_state {
|
||||
unsigned char *pencils;
|
||||
unsigned char *cell_errors;
|
||||
unsigned char *hint_errors;
|
||||
unsigned char *hints_done;
|
||||
unsigned char count_errors[3];
|
||||
int solved;
|
||||
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);
|
||||
for (i=0;i<2*state->common->num_paths;i++)
|
||||
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++)
|
||||
state->count_errors[i] = FALSE;
|
||||
|
||||
@ -332,6 +337,13 @@ static game_state *dup_game(const game_state *state)
|
||||
}
|
||||
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[1] = state->count_errors[1];
|
||||
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);
|
||||
sfree(state->common);
|
||||
}
|
||||
if (state->hints_done != NULL) sfree(state->hints_done);
|
||||
if (state->hint_errors != NULL) sfree(state->hint_errors);
|
||||
if (state->cell_errors != NULL) sfree(state->cell_errors);
|
||||
if (state->pencils != NULL) sfree(state->pencils);
|
||||
@ -1662,12 +1675,40 @@ struct game_drawstate {
|
||||
unsigned char count_errors[3];
|
||||
unsigned char *cell_errors;
|
||||
unsigned char *hint_errors;
|
||||
unsigned char *hints_done;
|
||||
|
||||
int hx, hy, hshow, hpencil; /* as for game_ui. */
|
||||
int hflash;
|
||||
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 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;
|
||||
@ -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)
|
||||
{
|
||||
int x,n,p,i;
|
||||
int x,y,n,p,i;
|
||||
char c;
|
||||
int correct;
|
||||
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;
|
||||
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++;
|
||||
}
|
||||
|
||||
@ -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 + 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;
|
||||
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);
|
||||
for (i=0;i<2*state->common->num_paths;i++)
|
||||
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->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) {
|
||||
sfree(ds->hints_done);
|
||||
sfree(ds->hint_errors);
|
||||
sfree(ds->cell_errors);
|
||||
sfree(ds->pencils);
|
||||
@ -2325,6 +2384,8 @@ static void draw_path_hint(drawing *dr, game_drawstate *ds,
|
||||
color = COL_ERROR;
|
||||
else if (hflash)
|
||||
color = COL_FLASH;
|
||||
else if (ds->hints_done[hint_index])
|
||||
color = COL_DONE;
|
||||
else
|
||||
color = COL_TEXT;
|
||||
|
||||
@ -2453,6 +2514,11 @@ static int is_hint_stale(const game_drawstate *ds, int hflash,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ds->hints_done[index] != state->hints_done[index]) {
|
||||
ds->hints_done[index] = state->hints_done[index];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user