Cleanups:
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 21 May 2005 13:39:23 +0000 (13:39 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 21 May 2005 13:39:23 +0000 (13:39 +0000)
 - 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.

git-svn-id: svn://svn.tartarus.org/sgt/puzzles@5818 cda61777-01e9-0310-a592-d414129be87e

net.c
puzzles.but
rect.c

diff --git a/net.c b/net.c
index da9e54c..3520483 100644 (file)
--- a/net.c
+++ b/net.c
@@ -201,11 +201,11 @@ static void decode_params(game_params *ret, char const *string)
     char const *p = string;
 
     ret->width = atoi(p);
     char const *p = string;
 
     ret->width = atoi(p);
-    while (*p && isdigit(*p)) p++;
+    while (*p && isdigit((unsigned char)*p)) p++;
     if (*p == 'x') {
         p++;
         ret->height = atoi(p);
     if (*p == 'x') {
         p++;
         ret->height = atoi(p);
-        while (*p && isdigit(*p)) p++;
+        while (*p && isdigit((unsigned char)*p)) p++;
     } else {
         ret->height = ret->width;
     }
     } else {
         ret->height = ret->width;
     }
@@ -217,11 +217,12 @@ static void decode_params(game_params *ret, char const *string)
        } else if (*p == 'b') {
            p++;
             ret->barrier_probability = atof(p);
        } else if (*p == 'b') {
            p++;
             ret->barrier_probability = atof(p);
-           while (*p && isdigit(*p)) p++;
+           while (*p && (*p == '.' || isdigit((unsigned char)*p))) p++;
        } else if (*p == 'a') {
             p++;
            ret->unique = FALSE;
        } else if (*p == 'a') {
             p++;
            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';
     if (full && params->barrier_probability)
         len += sprintf(ret+len, "b%g", params->barrier_probability);
         ret[len++] = 'w';
     if (full && params->barrier_probability)
         len += sprintf(ret+len, "b%g", params->barrier_probability);
-    if (!params->unique)
+    if (full && !params->unique)
         ret[len++] = 'a';
     assert(len < lenof(ret));
     ret[len] = '\0';
         ret[len++] = 'a';
     assert(len < lenof(ret));
     ret[len] = '\0';
index bf2601b..fa7ce1a 100644 (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
 act as constraints on the solution (i.e., hints).
 
 higher number gives more barriers). Since barriers are immovable, they
 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{
 
 The grid generation in Net has been carefully arranged so that the
 \lcont{
 
 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}
 
 \cfg{winhelp-topic}{games.cube}
 \C{cube} \i{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}
-and \e{Height} parameters, which are self-explanatory.
+These parameters are available from the \q{Custom...} option on the
+\q{Type} menu.
+
+\dt \e{Width}, \e{Height}
+
+\dd Size of grid, in squares.
+
+\dt \e{Expansion factor}
 
 
-\q{Expansion factor} 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
+\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
 you specified, and then to expand it by adding rows and columns.
 
 Rectangles to essentially generate a \e{smaller} grid than the size
 you specified, and then to expand it by adding rows and columns.
 
+\lcont{
+
 The default expansion factor of zero means that Rectangles will
 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
 The default expansion factor of zero means that Rectangles will
 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
@@ -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
 to cover the entire grid, and the game becomes trivial.
 
 though, the game simply cannot generate more than a few rectangles
 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}
 
diff --git a/rect.c b/rect.c
index 524d97b..848dcd3 100644 (file)
--- a/rect.c
+++ b/rect.c
@@ -45,6 +45,7 @@ enum {
 struct game_params {
     int w, h;
     float expandfactor;
 struct game_params {
     int w, h;
     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->expandfactor = 0.0F;
 
     ret->w = ret->h = 7;
     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->h = h;
     ret->expandfactor = 0.0F;
     ret->w = w;
     ret->h = h;
     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') {
        string++;
        ret->expandfactor = atof(string);
     if (*string == 'e') {
        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);
     if (full && params->expandfactor)
         sprintf(data + strlen(data), "e%g", params->expandfactor);
     sprintf(data, "%dx%d", params->w, params->h);
     if (full && 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].ival = 0;
 
     ret[2].sval = dupstr(buf);
     ret[2].ival = 0;
 
-    ret[3].name = NULL;
-    ret[3].type = C_END;
+    ret[3].name = "Ensure unique solution";
+    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->h = atoi(cfg[1].sval);
     ret->expandfactor = atof(cfg[2].sval);
     ret->w = atoi(cfg[0].sval);
     ret->h = atoi(cfg[1].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,
                 }
             }
 
                 }
             }
 
-           ret = rect_solver(params->w, params->h, nnumbers, nd, rs);
+           if (params->unique)
+               ret = rect_solver(params->w, params->h, nnumbers, nd, rs);
+           else
+               ret = TRUE;            /* allow any number placement at all */
 
             if (ret) {
                 /*
 
             if (ret) {
                 /*