int merge_check(Puzzle *puz, Solution *sol) { MergeElem *m; //dir_t z; int found= 0; for (m= merge_list; m != NULL; m= m->next) { if (m->maxc == merge_no && m->cell != NULL) { if (VM) { printf("M: FOUND MERGED CONSEQUENCE ON CELL (%d,%d) BITS ", m->cell->line[0], m->cell->line[1]); dump_bits(stdout, puz, m->bit); printf("\n"); } /* Add to history as a necessary consequence */ add_hist(puz, m->cell, 0); /* Set the new value in the cell */ #ifdef LIMITCOLORS oldval[0]= m->cell->bit[0]; m->cell->bit[0]&= ~m->bit[0]; #else for (z= 0; z < fbit_size; z++) { oldval[z]= m->cell->bit[z]; m->cell->bit[z]&= ~m->bit[z]; } #endif if (puz->ncolor <= 2) m->cell->n= 1; else count_cell(puz,m->cell); if (m->cell->n == 1) solved_a_cell(puz, m->cell,1); /* Add rows/columns containing this cell to the job list */ add_jobs(puz, sol, -1, m->cell, 0, oldval); found= 1; } /* Reset to unused state */ m->cell= NULL; } if (VM && !found) printf("M: NO MERGE CONSEQUENCES\n"); merge_list= NULL; merge_no= -1; merging= 0; return found; }
void guess_cell(Puzzle *puz, Solution *sol, Cell *cell, color_t c) { dir_t k; Hist *h; /* Save old cell in backtrack history */ h= add_hist(puz, cell, 1); /* Set just that one color */ cell->n= 1; fbit_setonly(cell->bit,c); solved_a_cell(puz,cell, 1); /* Put all crossing lines onto the job list */ add_jobs(puz, sol, -1, cell, 0, h->bit); }
int backtrack(Puzzle *puz, Solution *sol) { Hist *h; //color_t z, oldn, newn; //dir_t k; if (VB) printf("B: BACKTRACKING TO LAST GUESS\n"); /* Undo up to, but not including, the most recent branch point */ if (undo(puz,sol, 1)) { if (VB) printf("B: CANNOT BACKTRACK\n"); return 1; } if (VB) print_solution(stdout,puz,sol); /* This will be the branch point since undo() backed us up to it */ h= HIST(puz, puz->nhist-1); if (VB || WC(h->cell)) { printf("B: LAST GUESS WAS "); print_coord(stdout,puz,h->cell); printf(" |"); dump_bits(stdout,puz,h->bit); printf("| -> |"); dump_bits(stdout,puz,h->cell->bit); printf("|\n"); } /* If undoing a solved cell, uncount it */ if (h->cell->n == 1) solved_a_cell(puz, h->cell, -1); /* Reset any bits previously set */ #ifdef LIMITCOLORS h->cell->bit[0]= ((~h->cell->bit[0]) & h->bit[0]); #else for (z= 0; z < fbit_size; z++) h->cell->bit[z]= ((~h->cell->bit[z]) & h->bit[z]); #endif h->cell->n= h->n - h->cell->n; /* Since the bits set in h are always a superset of those in h->cell, this should always work */ /* If inverted cell is solved, count it */ if (h->cell->n == 1) solved_a_cell(puz, h->cell, 1); if (VB || WC(h->cell)) { printf("B: INVERTING GUESS TO |"); dump_bits(stdout,puz,h->cell->bit); printf("| (%d)\n",h->cell->n); } /* Now that we've backtracked to it and inverted it, it is no * longer a branch point. If there is no previous history, delete * this node. Otherwise, convert it into a non-branch point. * Next time we backtrack we will just delete it. */ if (puz->nhist == 1) puz->nhist= 0; else h->branch= 0; /* Remove everything from the job list except the lines containing * the inverted cell. */ if (maylinesolve) { flush_jobs(puz); add_jobs(puz, sol, -1, h->cell, 0, h->bit); } backtracks++; return 0; }
int undo(Puzzle *puz, Solution *sol, int leave_branch) { Hist *h; Clue *clue; Cell **line; dir_t k; int is_branch; line_t i; while (puz->nhist > 0) { h= HIST(puz, puz->nhist-1); /* Invalidate any saved positions for lines crossing undone cell. * We can't just have the fact that nhist < stamp mean the line is * invalid, because we might backtrack and then advance past stamp * again before we recheck the line. */ for (k= 0; k < puz->nset; k++) { i= h->cell->line[k]; clue= &(puz->clue[k][i]); line= sol->line[k][i]; if ((VL && VU) || WL(*clue)) printf("U: CHECK %s %d", CLUENAME(puz->type,k),i); left_undo(puz, clue, line, h->cell->index[k], h->bit); right_undo(puz, clue, line, h->cell->index[k], h->bit); if ((VL && VU) || WL(*clue)) printf("\n"); } is_branch= h->branch; if (!is_branch || !leave_branch) { /* If undoing a solved cell, decrement completion count */ if (h->cell->n == 1) solved_a_cell(puz, h->cell, -1); /* Restore saved value */ h->cell->n= h->n; fbit_cpy(h->cell->bit, h->bit); if (VU || WC(h->cell)) { printf("U: UNDOING CELL "); for (k= 0; k < puz->nset; k++) printf(" %d",h->cell->line[k]); printf(" TO "); dump_bits(stdout,puz,h->cell->bit); printf(" (%d)\n",h->cell->n); } puz->nhist--; } if (is_branch) return 0; } return 1; }