int i, ret = 1;
assert(copy->n == orig->n);
for (i = 0; i < copy->n; i++) {
- if (only_immutable && !copy->flags[i] & FLAG_IMMUTABLE) continue;
+ if (only_immutable && !(copy->flags[i] & FLAG_IMMUTABLE)) continue;
assert(copy->nums[i] >= 0);
assert(copy->nums[i] <= copy->n);
if (copy->nums[i] != orig->nums[i]) {
static char *validate_params(const game_params *params, int full)
{
- if (params->w < 2 || params->h < 2)
- return "Width and height must both be at least two";
- if (params->w == 2 && params->h == 2) /* leads to generation hang */
- return "Width and height cannot both be two";
-
+ if (params->w < 1) return "Width must be at least one";
+ if (params->h < 1) return "Height must be at least one";
+ if (full && params->w == 1 && params->h == 1)
+ /* The UI doesn't let us move these from unsolved to solved,
+ * so we disallow generating (but not playing) them. */
+ return "Width and height cannot both be one";
return NULL;
}
state->dirs[taili] = 0;
nfilled = 2;
+ assert(state->n > 1);
while (nfilled < state->n) {
/* Try and expand _from_ headi; keep going if there's only one
an = cell_adj(state, headi, aidx, adir);
} while (an == 1);
+ if (nfilled == state->n) break;
+
/* Try and expand _to_ taili; keep going if there's only one
* place to go to. */
an = cell_adj(state, taili, aidx, adir);
char *ret;
int headi, taili;
+ /* this shouldn't happen (validate_params), but let's play it safe */
+ if (params->w == 1 && params->h == 1) return dupstr("1a");
+
generate:
blank_game_into(state);
si = sy*w+sx; ei = ey*w+ex;
makelink(ret, si, ei);
} else if (sscanf(move, "%c%d,%d", &c, &sx, &sy) == 3) {
+ int sset;
+
if (c != 'C' && c != 'X') return NULL;
if (!INGRID(state, sx, sy)) return NULL;
si = sy*w+sx;
ret = dup_game(state);
- if (c == 'C') {
+ sset = state->nums[si] / (state->n+1);
+ if (c == 'C' || (c == 'X' && sset == 0)) {
/* Unlink the single cell we dragged from the board. */
unlink_cell(ret, si);
} else {
- int i, set, sset = state->nums[si] / (state->n+1);
+ int i, set;
for (i = 0; i < state->n; i++) {
/* Unlink all cells in the same set as the one we dragged
* from the board. */
const struct game thegame = {
"Signpost", "games.signpost", "signpost",
default_params,
- game_fetch_preset,
+ game_fetch_preset, NULL,
decode_params,
encode_params,
free_params,