7
+ char *hl_error, *vl_error;
10
static char *game_text_format(game_state *state);
12
ds->hl = snewn(HL_COUNT(state), char);
13
ds->vl = snewn(VL_COUNT(state), char);
14
ds->clue_error = snewn(SQUARE_COUNT(state), char);
15
+ ds->hl_error = snewn(LINE_COUNT(state), char);
16
+ ds->vl_error = ds->hl_error + HL_COUNT(state);
19
memset(ds->hl, LINE_UNKNOWN, HL_COUNT(state));
20
memset(ds->vl, LINE_UNKNOWN, VL_COUNT(state));
21
memset(ds->clue_error, 0, SQUARE_COUNT(state));
22
+ memset(ds->hl_error, 0, LINE_COUNT(state));
27
static void game_free_drawstate(drawing *dr, game_drawstate *ds)
29
+ sfree(ds->hl_error);
30
sfree(ds->clue_error);
33
@@ -3264,6 +3269,37 @@
34
* Drawing and mouse-handling
37
+static int follow_line(game_state *state, int *prevdir, int *x, int *y,
40
+ if (dot_order(state, *x, *y, LINE_YES) != 2) {
45
+ if (LEFTOF_DOT(state, *x, *y) == LINE_YES && *prevdir != 'L') {
48
+ } else if (RIGHTOF_DOT(state, *x, *y) == LINE_YES &&
52
+ } else if (ABOVE_DOT(state, *x, *y) == LINE_YES &&
56
+ } else if (BELOW_DOT(state, *x, *y) == LINE_YES &&
61
+ assert(!"Can't happen"); /* dot_order guarantees success */
68
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
69
int x, int y, int button)
71
@@ -3443,38 +3479,9 @@
72
* to see if it's part of a loop.
76
- int order = dot_order(newstate, x, y, LINE_YES);
78
- goto completion_check_done;
80
- if (LEFTOF_DOT(newstate, x, y) == LINE_YES && prevdir != 'L') {
83
- } else if (RIGHTOF_DOT(newstate, x, y) == LINE_YES &&
87
- } else if (ABOVE_DOT(newstate, x, y) == LINE_YES &&
91
- } else if (BELOW_DOT(newstate, x, y) == LINE_YES &&
96
- assert(!"Can't happen"); /* dot_order guarantees success */
101
- if (x == i && y == j)
105
- if (x != i || y != j || looplen == 0)
106
- goto completion_check_done;
107
+ while (follow_line(newstate, &prevdir, &x, &y, &looplen) &&
108
+ !(x == i && y == j))
112
* We've traced our way round a loop, and we know how many
113
@@ -3529,6 +3536,8 @@
115
int line_colour, flash_changed;
118
+ char *old_hl_error, *old_vl_error;
122
@@ -3575,6 +3584,69 @@
123
line_colour = COL_FOREGROUND;
126
+ old_hl_error = ds->hl_error;
127
+ old_vl_error = ds->vl_error;
128
+ ds->hl_error = snewn(LINE_COUNT(state), char);
129
+ ds->vl_error = ds->hl_error + HL_COUNT(state);
130
+ memset(ds->hl_error, 0, LINE_COUNT(state));
132
+ if (state->solved) {
135
+ /* Highlight non-solution loops as errors */
137
+ for (j = 0; j <= state->h; j++) {
138
+ for (i = 0; i < state->w; i++) {
139
+ if (!ds->hl_error[HL_INDEX(state, i, j)] &&
140
+ RIGHTOF_DOT(state, i, j) == LINE_YES) {
145
+ while (follow_line(state, &prevdir, &x, &y, &looplen) &&
146
+ !(x == i && y == j))
148
+ if (looplen != 0) {
151
+ follow_line(state, &prevdir, &x, &y, &looplen);
154
+ ds->hl_error[HL_INDEX(state, x, y)] = TRUE;
157
+ ds->hl_error[HL_INDEX(state, x - 1, y)] = TRUE;
160
+ ds->vl_error[VL_INDEX(state, x, y)] = TRUE;
163
+ ds->vl_error[VL_INDEX(state, x, y - 1)] = TRUE;
166
+ } while (!(x == i && y == j));
172
+ /* Highlight dots with >2 lines as errors */
173
+ for (j = 0; j <= state->h; j++) {
174
+ for (i = 0; i <= state->w; i++) {
175
+ if (dot_order(state, i, j, LINE_YES) > 2) {
176
+ if (RIGHTOF_DOT(state, i, j) == LINE_YES)
177
+ ds->hl_error[HL_INDEX(state, i, j)] = TRUE;
178
+ if (LEFTOF_DOT(state, i, j) == LINE_YES)
179
+ ds->hl_error[HL_INDEX(state, i - 1, j)] = TRUE;
180
+ if (BELOW_DOT(state, i, j) == LINE_YES)
181
+ ds->vl_error[VL_INDEX(state, i, j)] = TRUE;
182
+ if (ABOVE_DOT(state, i, j) == LINE_YES)
183
+ ds->vl_error[VL_INDEX(state, i, j - 1)] = TRUE;
189
#define CROSS_SIZE (3 * LINEWIDTH / 2)
191
/* Redraw clue colours if necessary */
192
@@ -3588,8 +3660,11 @@
193
c[0] = CLUE2CHAR(CLUE_AT(state, i, j));
196
- clue_mistake = (square_order(state, i, j, LINE_YES) > n ||
197
- square_order(state, i, j, LINE_NO ) > (4-n));
199
+ clue_mistake = square_order(state, i, j, LINE_YES) != n;
201
+ clue_mistake = (square_order(state, i, j, LINE_YES) > n ||
202
+ square_order(state, i, j, LINE_NO ) > (4-n));
204
if (clue_mistake != ds->clue_error[SQUARE_INDEX(state, i, j)]) {
206
@@ -3610,10 +3685,6 @@
210
- /* I've also had a request to colour lines red if they make a non-solution
211
- * loop, or if more than two lines go into any point. I think that would
212
- * be good some time. */
214
#define CLEAR_VL(i, j) \
217
@@ -3654,13 +3725,16 @@
220
if (ds->vl[VL_INDEX(state, i, j)] != BELOW_DOT(state, i, j) ||
221
+ ds->vl_error[VL_INDEX(state, i, j)] !=
222
+ old_vl_error[VL_INDEX(state, i, j)] ||
226
BORDER + i * TILE_SIZE - LINEWIDTH/2,
227
BORDER + j * TILE_SIZE + LINEWIDTH - LINEWIDTH/2,
228
LINEWIDTH, TILE_SIZE - LINEWIDTH,
230
+ ds->vl_error[VL_INDEX(state, i, j)] ?
231
+ COL_MISTAKE : line_colour);
235
@@ -3694,13 +3768,16 @@
238
if (ds->hl[HL_INDEX(state, i, j)] != RIGHTOF_DOT(state, i, j) ||
239
+ ds->hl_error[HL_INDEX(state, i, j)] !=
240
+ old_hl_error[HL_INDEX(state, i, j)] ||
244
BORDER + i * TILE_SIZE + LINEWIDTH - LINEWIDTH/2,
245
BORDER + j * TILE_SIZE - LINEWIDTH/2,
246
TILE_SIZE - LINEWIDTH, LINEWIDTH,
248
+ ds->hl_error[HL_INDEX(state, i, j)] ?
249
+ COL_MISTAKE : line_colour);
253
@@ -3723,6 +3800,8 @@
255
ds->hl[HL_INDEX(state, i, j)] = RIGHTOF_DOT(state, i, j);
258
+ sfree(old_hl_error);
261
static float game_flash_length(game_state *oldstate, game_state *newstate,