X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/149255d7ed0f808783624fcaaf8c3449cf99c851..63ed24043747435fc5b67339248426ca236e0739:/unequal.c diff --git a/unequal.c b/unequal.c index 74eba79..320dedf 100644 --- a/unequal.c +++ b/unequal.c @@ -408,6 +408,11 @@ static int c2n(int c, int order) { return -1; } +static int game_can_format_as_text_now(game_params *params) +{ + return TRUE; +} + static char *game_text_format(game_state *state) { int x, y, len, n; @@ -631,7 +636,7 @@ static int solver_grid(digit *grid, int o, int maxdiff, void *ctx) game_solver *solver; struct latin_solver *lsolver; struct latin_solver_scratch *scratch; - int ret, diff = DIFF_LATIN, extreme; + int ret, diff = DIFF_LATIN; assert(maxdiff <= DIFF_RECURSIVE); @@ -668,18 +673,28 @@ cont: if (maxdiff <= DIFF_EASY) break; - ret = latin_solver_diff_set(lsolver, scratch, &extreme); + /* Row- and column-wise set elimination */ + ret = latin_solver_diff_set(lsolver, scratch, 0); if (ret < 0) { diff = DIFF_IMPOSSIBLE; goto got_result; } else if (ret > 0) { - diff = max(diff, extreme ? DIFF_EXTREME : DIFF_SET); + diff = max(diff, DIFF_SET); goto cont; } if (maxdiff <= DIFF_SET) break; + ret = latin_solver_diff_set(lsolver, scratch, 1); + if (ret < 0) { + diff = DIFF_IMPOSSIBLE; + goto got_result; + } else if (ret > 0) { + diff = max(diff, DIFF_EXTREME); + goto cont; + } + /* * Forcing chains. */ @@ -870,7 +885,7 @@ static int gg_best_clue(game_state *state, int *scratch, digit *latin) } #endif - for (i = 0; i < ls; i++) { + for (i = ls; i-- > 0 ;) { if (!gg_place_clue(state, scratch[i], latin, 1)) continue; loc = scratch[i] / 5; @@ -886,7 +901,7 @@ static int gg_best_clue(game_state *state, int *scratch, digit *latin) best = i; maxposs = nposs; minclues = nclues; #ifdef STANDALONE_SOLVER if (solver_show_working) - printf("gg_best_clue: b%d (%d,%d) new best [%d poss, %d clues].", + printf("gg_best_clue: b%d (%d,%d) new best [%d poss, %d clues].\n", best, x, y, nposs, nclues); #endif } @@ -961,7 +976,8 @@ static void game_strip(game_state *new, int *scratch, digit *latin, gg_solved++; if (solver_state(copy, difficulty) != 1) { /* put clue back, we can't solve without it. */ - assert(gg_place_clue(new, scratch[i], latin, 0) == 1); + int ret = gg_place_clue(new, scratch[i], latin, 0); + assert(ret == 1); } else { #ifdef STANDALONE_SOLVER if (solver_show_working) @@ -985,14 +1001,15 @@ static char *new_game_desc(game_params *params, random_state *rs, { digit *sq = NULL; int i, x, y, retlen, k, nsol; - int o2 = params->order * params->order, ntries = 0; + int o2 = params->order * params->order, ntries = 1; int *scratch, lscratch = o2*5; char *ret, buf[80]; game_state *state = blank_game(params->order); /* Generate a list of 'things to strip' (randomised later) */ scratch = snewn(lscratch, int); - for (i = 0; i < lscratch; i++) scratch[i] = i; + /* Put the numbers (4 mod 5) before the inequalities (0-3 mod 5) */ + for (i = 0; i < lscratch; i++) scratch[i] = (i%o2)*5 + 4 - (i/o2); generate: #ifdef STANDALONE_SOLVER @@ -1003,7 +1020,9 @@ generate: if (sq) sfree(sq); sq = latin_generate(params->order, rs); latin_debug(sq, params->order); - shuffle(scratch, lscratch, sizeof(int), rs); + /* Separately shuffle the numeric and inequality clues */ + shuffle(scratch, lscratch/5, sizeof(int), rs); + shuffle(scratch+lscratch/5, 4*lscratch/5, sizeof(int), rs); memset(state->nums, 0, o2 * sizeof(digit)); memset(state->flags, 0, o2 * sizeof(unsigned int)); @@ -1020,7 +1039,7 @@ generate: if (nsol > 0) { #ifdef STANDALONE_SOLVER if (solver_show_working) - printf("game_assemble: puzzle as generated is too easy."); + printf("game_assemble: puzzle as generated is too easy.\n"); #endif if (ntries < MAXTRIES) { ntries++; @@ -1028,7 +1047,7 @@ generate: } #ifdef STANDALONE_SOLVER if (solver_show_working) - printf("Unable to generate %s %dx%d after %d attempts.", + printf("Unable to generate %s %dx%d after %d attempts.\n", unequal_diffnames[params->diff], params->order, params->order, MAXTRIES); #endif @@ -1037,7 +1056,7 @@ generate: } #ifdef STANDALONE_SOLVER if (solver_show_working) - printf("new_game_desc: generated %s puzzle; %d attempts (%d solver).", + printf("new_game_desc: generated %s puzzle; %d attempts (%d solver).\n", unequal_diffnames[params->diff], ntries, gg_solved); #endif @@ -1252,7 +1271,8 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, button &= ~MOD_MASK; - if (x >= 0 && x < ds->order && y >= 0 && y < ds->order) { + if (x >= 0 && x < ds->order && ((ox - COORD(x)) <= TILE_SIZE) && + y >= 0 && y < ds->order && ((oy - COORD(y)) <= TILE_SIZE)) { if (button == LEFT_BUTTON) { /* normal highlighting for non-immutable squares */ if (GRID(state, flags, x, y) & F_IMMUTABLE) @@ -1309,7 +1329,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, static game_state *execute_move(game_state *state, char *move) { game_state *ret = NULL; - int x, y, n, i; + int x, y, n, i, rc; debug(("execute_move: %s", move)); @@ -1345,7 +1365,8 @@ static game_state *execute_move(game_state *state, char *move) p++; } if (*p) goto badmove; - assert(check_complete(ret->nums, ret, 1) > 0); + rc = check_complete(ret->nums, ret, 1); + assert(rc > 0); return ret; } else if (move[0] == 'H') { return solver_hint(state, NULL, DIFF_EASY, DIFF_EASY); @@ -1720,7 +1741,7 @@ const struct game thegame = { dup_game, free_game, TRUE, solve_game, - TRUE, game_text_format, + TRUE, game_can_format_as_text_now, game_text_format, new_ui, free_ui, encode_ui, @@ -1738,7 +1759,7 @@ const struct game thegame = { TRUE, FALSE, game_print_size, game_print, FALSE, /* wants_statusbar */ FALSE, game_timing_state, - 0, /* flags */ + REQUIRE_RBUTTON | REQUIRE_NUMPAD, /* flags */ }; /* ----------------------------------------------------------------------