+config_item *game_configure(game_params *params)
+{
+ config_item *ret = snewn(4, config_item);
+ char buf[80];
+
+ ret[0].name = "Type of solid";
+ ret[0].type = C_CHOICES;
+ ret[0].sval = ":Tetrahedron:Cube:Octahedron:Icosahedron";
+ ret[0].ival = params->solid;
+
+ ret[1].name = "Width / top";
+ ret[1].type = C_STRING;
+ sprintf(buf, "%d", params->d1);
+ ret[1].sval = dupstr(buf);
+ ret[1].ival = 0;
+
+ ret[2].name = "Height / bottom";
+ ret[2].type = C_STRING;
+ sprintf(buf, "%d", params->d2);
+ ret[2].sval = dupstr(buf);
+ ret[2].ival = 0;
+
+ ret[3].name = NULL;
+ ret[3].type = C_END;
+ ret[3].sval = NULL;
+ ret[3].ival = 0;
+
+ return ret;
+}
+
+game_params *custom_params(config_item *cfg)
+{
+ game_params *ret = snew(game_params);
+
+ ret->solid = cfg[0].ival;
+ ret->d1 = atoi(cfg[1].sval);
+ ret->d2 = atoi(cfg[2].sval);
+
+ return ret;
+}
+
+static void count_grid_square_callback(void *ctx, struct grid_square *sq)
+{
+ int *classes = (int *)ctx;
+ int thisclass;
+
+ if (classes[4] == 4)
+ thisclass = sq->tetra_class;
+ else if (classes[4] == 2)
+ thisclass = sq->flip;
+ else
+ thisclass = 0;
+
+ classes[thisclass]++;
+}
+
+char *validate_params(game_params *params)
+{
+ int classes[5];
+ int i;
+
+ if (params->solid < 0 || params->solid >= lenof(solids))
+ return "Unrecognised solid type";
+
+ if (solids[params->solid]->order == 4) {
+ if (params->d1 <= 0 || params->d2 <= 0)
+ return "Both grid dimensions must be greater than zero";
+ } else {
+ if (params->d1 <= 0 && params->d2 <= 0)
+ return "At least one grid dimension must be greater than zero";
+ }
+
+ for (i = 0; i < 4; i++)
+ classes[i] = 0;
+ if (params->solid == TETRAHEDRON)
+ classes[4] = 4;
+ else if (params->solid == OCTAHEDRON)
+ classes[4] = 2;
+ else
+ classes[4] = 1;
+ enum_grid_squares(params, count_grid_square_callback, classes);
+
+ for (i = 0; i < classes[4]; i++)
+ if (classes[i] < solids[params->solid]->nfaces / classes[4])
+ return "Not enough grid space to place all blue faces";
+
+ if (grid_area(params->d1, params->d2, solids[params->solid]->order) <
+ solids[params->solid]->nfaces + 1)
+ return "Not enough space to place the solid on an empty square";
+
+ return NULL;
+}
+