#define CONFIG(upper,title,lower,fn) ":" #title
#define SOLVER_FN_DECL(upper,title,lower,fn) static int fn(solver_state *);
#define SOLVER_FN(upper,title,lower,fn) &fn,
-enum diff { DIFFLIST(ENUM) DIFF_MAX };
+enum { DIFFLIST(ENUM) DIFF_MAX };
static char const *const diffnames[] = { DIFFLIST(TITLE) };
static char const diffchars[] = DIFFLIST(ENCODE);
#define DIFFCONFIG DIFFLIST(CONFIG)
struct game_params {
int w, h;
- enum diff diff;
+ int diff;
int rec;
};
static int dot_order(const game_state* state, int i, int j, char line_type);
static int square_order(const game_state* state, int i, int j, char line_type);
static solver_state *solve_game_rec(const solver_state *sstate,
- enum diff diff);
+ int diff);
#ifdef DEBUG_CACHES
static void check_caches(const solver_state* sstate);
}
}
-static solver_state *new_solver_state(const game_state *state, enum diff diff) {
+static solver_state *new_solver_state(const game_state *state, int diff) {
int i, j;
solver_state *ret = snew(solver_state);
static int game_fetch_preset(int i, char **name, game_params **params)
{
- const game_params *tmppar;
+ game_params *tmppar;
char buf[80];
if (i < 0 || i >= lenof(presets))
return FALSE;
- tmppar = &presets[i];
- *params = dup_params((game_params *)tmppar);
+ tmppar = snew(game_params);
+ *tmppar = presets[i];
+ *params = tmppar;
sprintf(buf, "%dx%d %s", tmppar->h, tmppar->w, diffnames[tmppar->diff]);
*name = dupstr(buf);
* and custom_params will never generate anything that isn't
* within range.
*/
- assert(params->diff >= 0 && params->diff < DIFF_MAX);
+ assert(params->diff < DIFF_MAX);
return NULL;
}
dp += sprintf(dp, "%c", (int)(empty_count + 'a' - 1));
empty_count = 0;
}
- dp += sprintf(dp, "%c", CLUE2CHAR(CLUE_AT(state, i, j)));
+ dp += sprintf(dp, "%c", (int)CLUE2CHAR(CLUE_AT(state, i, j)));
}
}
if (empty_count)
- dp += sprintf(dp, "%c", (empty_count + 'a' - 1));
+ dp += sprintf(dp, "%c", (int)(empty_count + 'a' - 1));
retval = dupstr(description);
sfree(description);
rp += sprintf(rp, " \n");
for (i = 0; i < state->w; ++i) {
DRAW_VL;
- rp += sprintf(rp, "%c", CLUE2CHAR(CLUE_AT(state, i, j)));
+ rp += sprintf(rp, "%c", (int)CLUE2CHAR(CLUE_AT(state, i, j)));
}
DRAW_VL;
rp += sprintf(rp, "\n");
sfree(board);
}
-static int game_has_unique_soln(const game_state *state, enum diff diff)
+static int game_has_unique_soln(const game_state *state, int diff)
{
int ret;
solver_state *sstate_new;
/* Remove clues one at a time at random. */
static game_state *remove_clues(game_state *state, random_state *rs,
- enum diff diff)
+ int diff)
{
int *square_list, squares;
game_state *ret = dup_game(state), *saved_ret;
state = state_new;
if (params->diff > 0 && game_has_unique_soln(state, params->diff-1)) {
+#ifdef SHOW_WORKING
fprintf(stderr, "Rejecting board, it is too easy\n");
+#endif
goto newboard_please;
}
(d==DLINE_DR) ? "DLINE_DR": \
"oops")
-static const struct dline *get_dline(enum dline_desc desc)
-{
- return &dlines[desc];
-}
+#define CHECK_DLINE_SENSIBLE(d) assert(dlines[(d)].dx != -1 && dlines[(d)].dy != -1)
/* This will fail an assertion if the directions handed to it are the same, as
* no dline corresponds to that */
static enum dline_desc dline_desc_from_dirs(enum direction dir1,
enum direction dir2)
{
- const struct dline *dl;
int i;
assert (dir1 != dir2);
for (i = 0; i < lenof(dlines); ++i) {
- dl = &dlines[i];
- if ((dir1 == dl->dir1 && dir2 == dl->dir2) ||
- (dir1 == dl->dir2 && dir2 == dl->dir1)) {
- return dl->desc;
+ if ((dir1 == dlines[i].dir1 && dir2 == dlines[i].dir2) ||
+ (dir1 == dlines[i].dir2 && dir2 == dlines[i].dir1)) {
+ return dlines[i].desc;
}
}
* dline corresponding to the dot or square at [i,j]. You'll get an assertion
* failure if you talk about a dline that doesn't exist, ie if you ask about
* non-touching lines around a square. */
-static inline int get_dot_dline(const game_state *state, const char *dline_array,
+static int get_dot_dline(const game_state *state, const char *dline_array,
int i, int j, enum dline_desc desc)
{
/* fprintf(stderr, "get_dot_dline %p [%d,%d] %s\n", dline_array, i, j, DL2STR(desc)); */
static int get_square_dline(game_state *state, char *dline_array,
int i, int j, enum dline_desc desc)
{
- const struct dline *dl = get_dline(desc);
- assert(dl->dx != -1 && dl->dy != -1);
+ CHECK_DLINE_SENSIBLE(desc);
/* fprintf(stderr, "get_square_dline %p [%d,%d] %s\n", dline_array, i, j, DL2STR(desc)); */
- return BIT_SET(dline_array[(i+dl->dx) + (state->w + 1) * (j+dl->dy)],
+ return BIT_SET(dline_array[(i+dlines[desc].dx) + (state->w + 1) * (j+dlines[desc].dy)],
desc);
}
#endif
)
{
- const struct dline *dl = get_dline(desc);
int ret;
- assert(dl->dx != -1 && dl->dy != -1);
- ret = SET_BIT(dline_array[(i+dl->dx) + (state->w + 1) * (j+dl->dy)], desc);
+ CHECK_DLINE_SENSIBLE(desc);
+ ret = SET_BIT(dline_array[(i+dlines[desc].dx) + (state->w + 1) * (j+dlines[desc].dy)], desc);
#ifdef SHOW_WORKING
if (ret)
fprintf(stderr, "set_square_dline %p [%d,%d] %s (%s)\n", dline_array, i, j, DL2STR(desc), reason);
static int dline_both_unknown(const game_state *state, int i, int j,
enum dline_desc desc)
{
- const struct dline *dl = get_dline(desc);
return
- (get_line_status_from_point(state, i, j, dl->dir1) == LINE_UNKNOWN) &&
- (get_line_status_from_point(state, i, j, dl->dir2) == LINE_UNKNOWN);
+ (get_line_status_from_point(state, i, j, dlines[desc].dir1) == LINE_UNKNOWN) &&
+ (get_line_status_from_point(state, i, j, dlines[desc].dir2) == LINE_UNKNOWN);
}
#define SQUARE_DLINES \
#define SQUARE_LINE(dx, dy, linedir, dir_dot, sqdir) \
can[sqdir] = \
edsf_canonify(sstate->hard->linedsf, \
- LINEDSF_INDEX(sstate->state, x+dx, y+dy, linedir), \
+ LINEDSF_INDEX(sstate->state, x+(dx), y+(dy), linedir), \
&inv[sqdir]);
SQUARE_LINES;
* consider {i,j} in the opposite order. */
#define SQUARE_LINE(dx, dy, dir, c, sqdir) \
if (j == sqdir) { \
- retval = set_line_bydot(sstate, x+dx, y+dy, dir, line_new); \
+ retval = set_line_bydot(sstate, x+(dx), y+(dy), dir, line_new); \
if (retval) { \
break; \
} \
int i, int j, enum line_state line_new)
{
int retval = FALSE;
- const struct dline *dl = get_dline(dd);
+ const struct dline dll = dlines[dd], *dl = &dll;
#if 0
fprintf(stderr, "square_setboth_in_dline %s [%d,%d] to %d\n",
DL2STR(dd), i, j, line_new);
#endif
- assert(dl->dx != -1 && dl->dy != -1);
+ CHECK_DLINE_SENSIBLE(dd);
retval |=
set_line_bydot(sstate, i+dl->dx, j+dl->dy, dl->dir1, line_new);
{
int i, j, h, w, current_yes, current_no;
game_state *state;
- enum diff diff = DIFF_MAX;
+ int diff = DIFF_MAX;
state = sstate->state;
h = state->h;
int i, j;
game_state *state = sstate->state;
enum dline_desc dd;
- enum diff diff = DIFF_MAX;
+ int diff = DIFF_MAX;
FORALL_SQUARES(state, i, j) {
if (sstate->square_solved[SQUARE_INDEX(state, i, j)])
const int h=state->h, w=state->w;
enum direction dir1, dir2;
int can1, can2, inv1, inv2;
- enum diff diff = DIFF_MAX;
- const struct dline *dl;
+ int diff = DIFF_MAX;
enum dline_desc dd;
FORALL_SQUARES(state, i, j) {
continue;
FORALL_DOT_DLINES(dd) {
- dl = get_dline(dd);
+ const struct dline dll = dlines[dd], *dl = &dll;
if (i == 0 && (dl->dir1 == LEFT || dl->dir2 == LEFT))
continue;
if (i == w && (dl->dir1 == RIGHT || dl->dir2 == RIGHT))
/* This will return a dynamically allocated solver_state containing the (more)
* solved grid */
static solver_state *solve_game_rec(const solver_state *sstate_start,
- enum diff diff)
+ int diff)
{
int i, j;
int w, h;
/*
* Lines. (At the moment, I'm not bothering with crosses.)
*/
- FORALL_VL(state, x, y) {
+ FORALL_HL(state, x, y) {
if (RIGHTOF_DOT(state, x, y) == LINE_YES)
draw_rect(dr, BORDER + x * TILE_SIZE,
BORDER + y * TILE_SIZE - LINEWIDTH/2,
TILE_SIZE, (LINEWIDTH/2) * 2 + 1, ink);
}
- FORALL_HL(state, x, y) {
+ FORALL_VL(state, x, y) {
if (BELOW_DOT(state, x, y) == LINE_YES)
draw_rect(dr, BORDER + x * TILE_SIZE - LINEWIDTH/2,
BORDER + y * TILE_SIZE,
#endif
const struct game thegame = {
- "Loopy", "games.loopy",
+ "Loopy", "games.loopy", "loopy",
default_params,
game_fetch_preset,
decode_params,