- game_state *state = (game_state *)ctx;
- game_solver *solver;
- struct latin_solver *lsolver;
- struct latin_solver_scratch *scratch;
- int ret, diff = DIFF_LATIN;
-
- assert(maxdiff <= DIFF_RECURSIVE);
-
- assert(state->order == o);
- solver = new_solver(grid, state);
-
- lsolver = &solver->latin;
- scratch = latin_solver_new_scratch(lsolver);
-
- while (1) {
-cont:
- ret = latin_solver_diff_simple(lsolver);
- if (ret < 0) {
- diff = DIFF_IMPOSSIBLE;
- goto got_result;
- } else if (ret > 0) {
- diff = max(diff, DIFF_LATIN);
- goto cont;
- }
-
- if (maxdiff <= DIFF_LATIN)
- break;
-
- if (state->adjacent) {
- /* Adjacent-specific: set possibles from known numbers
- * and adjacency clues. */
- ret = solver_adjacent(solver);
- } else {
- /* Unequal-specific: set possibles from chains of
- * inequalities. */
- ret = solver_links(solver);
- }
- if (ret < 0) {
- diff = DIFF_IMPOSSIBLE;
- goto got_result;
- } else if (ret > 0) {
- diff = max(diff, DIFF_EASY);
- goto cont;
- }
-
- if (maxdiff <= DIFF_EASY)
- break;
-
- /* 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, DIFF_SET);
- goto cont;
- }
-
- if (state->adjacent) {
- /* Adjacent-specific: set possibles from other possibles
- * and adjacency clues. */
- ret = solver_adjacent_set(solver);
- if (ret < 0) {
- diff = DIFF_IMPOSSIBLE;
- goto got_result;
- } else if (ret > 0) {
- diff = max(diff, DIFF_SET);
- goto cont;
- }
- }
-
- if (maxdiff <= DIFF_SET)
- break;