diff --git a/unruly.c b/unruly.c index 3e5463f..2ee4a69 100644 --- a/unruly.c +++ b/unruly.c @@ -81,6 +81,7 @@ struct game_params { int diff; }; #define DIFFLIST(A) \ + A(TRIVIAL,Trivial, t) \ A(EASY,Easy, e) \ A(NORMAL,Normal, n) \ @@ -95,6 +96,7 @@ static char const unruly_diffchars[] = DIFFLIST(ENCODE); #define DIFFCONFIG DIFFLIST(CONFIG) static const struct game_params unruly_presets[] = { + { 8, 8, false, DIFF_TRIVIAL}, { 8, 8, false, DIFF_EASY}, { 8, 8, false, DIFF_NORMAL}, {10, 10, false, DIFF_EASY}, @@ -743,6 +745,61 @@ static int unruly_solver_fill_row(game_state *state, int i, bool horizontal, return ret; } +static int unruly_solver_check_single_gap(game_state *state, + int *complete, bool horizontal, + int *rowcount, int *colcount, + char fill) +{ + int w2 = state->w2, h2 = state->h2; + int count = (horizontal ? h2 : w2); /* number of rows to check */ + int target = (horizontal ? w2 : h2) / 2; /* target number of 0s/1s */ + int *other = (horizontal ? rowcount : colcount); + + int ret = 0; + + int i; + /* Check for completed rows/cols for one number, then fill in the rest */ + for (i = 0; i < count; i++) { + if (complete[i] == target && other[i] == target - 1) { +#ifdef STANDALONE_SOLVER + if (solver_verbose) { + printf("Solver: Row %i has only one square left which must be " + "%c\n", i, (fill == N_ZERO ? '0' : '1')); + } +#endif + ret += unruly_solver_fill_row(state, i, horizontal, rowcount, + colcount, fill); + } + } + + return ret; +} + +static int unruly_solver_check_all_single_gap(game_state *state, + struct unruly_scratch *scratch) +{ + int ret = 0; + + ret += + unruly_solver_check_single_gap(state, scratch->ones_rows, true, + scratch->zeros_rows, + scratch->zeros_cols, N_ZERO); + ret += + unruly_solver_check_single_gap(state, scratch->ones_cols, false, + scratch->zeros_rows, + scratch->zeros_cols, N_ZERO); + ret += + unruly_solver_check_single_gap(state, scratch->zeros_rows, true, + scratch->ones_rows, + scratch->ones_cols, N_ONE); + ret += + unruly_solver_check_single_gap(state, scratch->zeros_cols, false, + scratch->ones_rows, + scratch->ones_cols, N_ONE); + + return ret; +} + static int unruly_solver_check_complete_nums(game_state *state, int *complete, bool horizontal, int *rowcount, int *colcount, @@ -1140,11 +1197,24 @@ static int unruly_solve_game(game_state *state, /* Keep using the simpler techniques while they produce results */ if (done) { - if (maxdiff < DIFF_EASY) - maxdiff = DIFF_EASY; + if (maxdiff < DIFF_TRIVIAL) + maxdiff = DIFF_TRIVIAL; continue; } + /* Check for rows with only one unfilled square */ + done += unruly_solver_check_all_single_gap(state, scratch); + + if (done) { + if (maxdiff < DIFF_TRIVIAL) + maxdiff = DIFF_TRIVIAL; + continue; + } + + /* Easy techniques */ + if (diff < DIFF_EASY) + break; + /* Check for completed rows */ done += unruly_solver_check_all_complete_nums(state, scratch);