Example #1
0
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;
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
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;
}