case '\r':
case '\n':
case '\b':
- case '\177':
button = 0;
break;
default:
- if (!isdigit(button)) return NULL;
+ if (button < '0' || button > '9') return NULL;
button -= '0';
if (button > (w == 2 && h == 2? 3: max(w, h))) return NULL;
}
static game_state *execute_move(game_state *state, char *move)
{
- game_state *new_state;
+ game_state *new_state = NULL;
const int sz = state->shared->params.w * state->shared->params.h;
if (*move == 's') {
} else {
int value;
char *endptr, *delim = strchr(move, '_');
- if (!delim) return NULL;
+ if (!delim) goto err;
value = strtol(delim+1, &endptr, 0);
- if (*endptr || endptr == delim+1) return NULL;
- if (value < 0 || value > 9) return NULL;
+ if (*endptr || endptr == delim+1) goto err;
+ if (value < 0 || value > 9) goto err;
new_state = dup_game(state);
while (*move) {
const int i = strtol(move, &endptr, 0);
- if (endptr == move) return NULL;
- if (i < 0 || i >= sz) return NULL;
+ if (endptr == move) goto err;
+ if (i < 0 || i >= sz) goto err;
new_state->board[i] = value;
if (*endptr == '_') break;
- if (*endptr != ',') return NULL;
+ if (*endptr != ',') goto err;
move = endptr + 1;
}
}
}
return new_state;
+
+err:
+ if (new_state) free_game(new_state);
+ return NULL;
}
/* ----------------------------------------------------------------------
/*
* Determine what we need to draw in this square.
*/
- int v = state->board[y*w+x];
+ int i = y*w+x, v = state->board[i];
int flags = 0;
if (flashy || !shading) {
/* clear all background flags */
- } else if (ui->sel && ui->sel[y*w+x]) {
+ } else if (ui && ui->sel && ui->sel[i]) {
flags |= HIGH_BG;
} else if (v) {
- int size = dsf_size(ds->dsf_scratch, y*w+x);
+ int size = dsf_size(ds->dsf_scratch, i);
if (size == v)
flags |= CORRECT_BG;
else if (size > v)
flags |= ERROR_BG;
+ else {
+ int rt = dsf_canonify(ds->dsf_scratch, i), j;
+ for (j = 0; j < w*h; ++j) {
+ int k;
+ if (dsf_canonify(ds->dsf_scratch, j) != rt) continue;
+ for (k = 0; k < 4; ++k) {
+ const int xx = j % w + dx[k], yy = j / w + dy[k];
+ if (xx >= 0 && xx < w && yy >= 0 && yy < h &&
+ state->board[yy*w + xx] == EMPTY)
+ goto noflag;
+ }
+ }
+ flags |= ERROR_BG;
+ noflag:
+ ;
+ }
}
- if (ui->cur_visible && x == ui->cur_x && y == ui->cur_y)
+ if (ui && ui->cur_visible && x == ui->cur_x && y == ui->cur_y)
flags |= CURSOR_SQ;
/*
return 0.0F;
}
+static int game_status(game_state *state)
+{
+ return state->completed ? +1 : 0;
+}
+
static int game_timing_state(game_state *state, game_ui *ui)
{
return TRUE;
game_redraw,
game_anim_length,
game_flash_length,
+ game_status,
TRUE, FALSE, game_print_size, game_print,
FALSE, /* wants_statusbar */
FALSE, game_timing_state,