Cleanups:

- fix documentation of Net's unique solution option (should have
   tested before last checkin)
 - make unique solutions optional in Rectangles too (same reasons)
 - tidy up various issues in parameter encoding in both games.

[originally from svn r5818]
This commit is contained in:
Simon Tatham
2005-05-21 13:39:23 +00:00
parent 862e25c90b
commit f3ba6f8bce
3 changed files with 63 additions and 23 deletions

11
net.c
View File

@ -201,11 +201,11 @@ static void decode_params(game_params *ret, char const *string)
char const *p = string; char const *p = string;
ret->width = atoi(p); ret->width = atoi(p);
while (*p && isdigit(*p)) p++; while (*p && isdigit((unsigned char)*p)) p++;
if (*p == 'x') { if (*p == 'x') {
p++; p++;
ret->height = atoi(p); ret->height = atoi(p);
while (*p && isdigit(*p)) p++; while (*p && isdigit((unsigned char)*p)) p++;
} else { } else {
ret->height = ret->width; ret->height = ret->width;
} }
@ -217,11 +217,12 @@ static void decode_params(game_params *ret, char const *string)
} else if (*p == 'b') { } else if (*p == 'b') {
p++; p++;
ret->barrier_probability = atof(p); ret->barrier_probability = atof(p);
while (*p && isdigit(*p)) p++; while (*p && (*p == '.' || isdigit((unsigned char)*p))) p++;
} else if (*p == 'a') { } else if (*p == 'a') {
p++; p++;
ret->unique = FALSE; ret->unique = FALSE;
} } else
p++; /* skip any other gunk */
} }
} }
@ -235,7 +236,7 @@ static char *encode_params(game_params *params, int full)
ret[len++] = 'w'; ret[len++] = 'w';
if (full && params->barrier_probability) if (full && params->barrier_probability)
len += sprintf(ret+len, "b%g", params->barrier_probability); len += sprintf(ret+len, "b%g", params->barrier_probability);
if (!params->unique) if (full && !params->unique)
ret[len++] = 'a'; ret[len++] = 'a';
assert(len < lenof(ret)); assert(len < lenof(ret));
ret[len] = '\0'; ret[len] = '\0';

View File

@ -346,15 +346,6 @@ barrier is placed between two tiles to prevent flow between them (a
higher number gives more barriers). Since barriers are immovable, they higher number gives more barriers). Since barriers are immovable, they
act as constraints on the solution (i.e., hints). act as constraints on the solution (i.e., hints).
\dt \e{Ensure unique solution}
\dd Normally, Net will make sure that the puzzles it presents have
only one solution. Puzzles with ambiguous sections can be more
difficult and more subtle, so if you like you can turn off this
feature and risk having ambiguous puzzles. (Also, finding \e{all}
the possible solutions can be an additional challenge for an
advanced player.)
\lcont{ \lcont{
The grid generation in Net has been carefully arranged so that the The grid generation in Net has been carefully arranged so that the
@ -370,6 +361,15 @@ from the original Net window.
} }
\dt \e{Ensure unique solution}
\dd Normally, Net will make sure that the puzzles it presents have
only one solution. Puzzles with ambiguous sections can be more
difficult and more subtle, so if you like you can turn off this
feature and risk having ambiguous puzzles. (Also, finding \e{all}
the possible solutions can be an additional challenge for an
advanced player.)
\C{cube} \i{Cube} \C{cube} \i{Cube}
\cfg{winhelp-topic}{games.cube} \cfg{winhelp-topic}{games.cube}
@ -613,15 +613,23 @@ When a rectangle of the correct size is completed, it will be shaded.
\H{rectangles-params} \I{parameters, for Rectangles}Rectangles parameters \H{rectangles-params} \I{parameters, for Rectangles}Rectangles parameters
The \q{Custom...} option on the \q{Type} menu offers you \e{Width} These parameters are available from the \q{Custom...} option on the
and \e{Height} parameters, which are self-explanatory. \q{Type} menu.
\q{Expansion factor} is a mechanism for changing the type of grids \dt \e{Width}, \e{Height}
generated by the program. Some people prefer a grid containing a few
large rectangles to one containing many small ones. So you can ask \dd Size of grid, in squares.
\dt \e{Expansion factor}
\dd This is a mechanism for changing the type of grids generated by
the program. Some people prefer a grid containing a few large
rectangles to one containing many small ones. So you can ask
Rectangles to essentially generate a \e{smaller} grid than the size Rectangles to essentially generate a \e{smaller} grid than the size
you specified, and then to expand it by adding rows and columns. you specified, and then to expand it by adding rows and columns.
\lcont{
The default expansion factor of zero means that Rectangles will The default expansion factor of zero means that Rectangles will
simply generate a grid of the size you ask for, and do nothing simply generate a grid of the size you ask for, and do nothing
further. If you set an expansion factor of (say) 0.5, it means that further. If you set an expansion factor of (say) 0.5, it means that
@ -636,6 +644,17 @@ and more intuitive playing style. If you set it \e{too} high,
though, the game simply cannot generate more than a few rectangles though, the game simply cannot generate more than a few rectangles
to cover the entire grid, and the game becomes trivial. to cover the entire grid, and the game becomes trivial.
}
\dt \e{Ensure unique solution}
\dd Normally, Rectangles will make sure that the puzzles it presents
have only one solution. Puzzles with ambiguous sections can be more
difficult and more subtle, so if you like you can turn off this
feature and risk having ambiguous puzzles. Also, finding \e{all} the
possible solutions can be an additional challenge for an advanced
player. Turning off this option can also speed up puzzle generation.
\C{netslide} \i{Netslide} \C{netslide} \i{Netslide}

26
rect.c
View File

@ -45,6 +45,7 @@ enum {
struct game_params { struct game_params {
int w, h; int w, h;
float expandfactor; float expandfactor;
int unique;
}; };
#define INDEX(state, x, y) (((y) * (state)->w) + (x)) #define INDEX(state, x, y) (((y) * (state)->w) + (x))
@ -84,6 +85,7 @@ static game_params *default_params(void)
ret->w = ret->h = 7; ret->w = ret->h = 7;
ret->expandfactor = 0.0F; ret->expandfactor = 0.0F;
ret->unique = TRUE;
return ret; return ret;
} }
@ -108,6 +110,7 @@ static int game_fetch_preset(int i, char **name, game_params **params)
ret->w = w; ret->w = w;
ret->h = h; ret->h = h;
ret->expandfactor = 0.0F; ret->expandfactor = 0.0F;
ret->unique = TRUE;
return TRUE; return TRUE;
} }
@ -135,6 +138,12 @@ static void decode_params(game_params *ret, char const *string)
if (*string == 'e') { if (*string == 'e') {
string++; string++;
ret->expandfactor = atof(string); ret->expandfactor = atof(string);
while (*string &&
(*string == '.' || isdigit((unsigned char)*string))) string++;
}
if (*string == 'a') {
string++;
ret->unique = FALSE;
} }
} }
@ -145,6 +154,8 @@ static char *encode_params(game_params *params, int full)
sprintf(data, "%dx%d", params->w, params->h); sprintf(data, "%dx%d", params->w, params->h);
if (full && params->expandfactor) if (full && params->expandfactor)
sprintf(data + strlen(data), "e%g", params->expandfactor); sprintf(data + strlen(data), "e%g", params->expandfactor);
if (full && !params->unique)
strcat(data, "a");
return dupstr(data); return dupstr(data);
} }
@ -174,10 +185,15 @@ static config_item *game_configure(game_params *params)
ret[2].sval = dupstr(buf); ret[2].sval = dupstr(buf);
ret[2].ival = 0; ret[2].ival = 0;
ret[3].name = NULL; ret[3].name = "Ensure unique solution";
ret[3].type = C_END; ret[3].type = C_BOOLEAN;
ret[3].sval = NULL; ret[3].sval = NULL;
ret[3].ival = 0; ret[3].ival = params->unique;
ret[4].name = NULL;
ret[4].type = C_END;
ret[4].sval = NULL;
ret[4].ival = 0;
return ret; return ret;
} }
@ -189,6 +205,7 @@ static game_params *custom_params(config_item *cfg)
ret->w = atoi(cfg[0].sval); ret->w = atoi(cfg[0].sval);
ret->h = atoi(cfg[1].sval); ret->h = atoi(cfg[1].sval);
ret->expandfactor = atof(cfg[2].sval); ret->expandfactor = atof(cfg[2].sval);
ret->unique = cfg[3].ival;
return ret; return ret;
} }
@ -1505,7 +1522,10 @@ static char *new_game_desc(game_params *params, random_state *rs,
} }
} }
if (params->unique)
ret = rect_solver(params->w, params->h, nnumbers, nd, rs); ret = rect_solver(params->w, params->h, nnumbers, nd, rs);
else
ret = TRUE; /* allow any number placement at all */
if (ret) { if (ret) {
/* /*