Example #1
0
void add_job(Puzzle *puz, dir_t k, line_t i, int depth, int bonus)
{
    Job *job;
    int priority;
    int j, par;

    /* Check if it is already on the job list */
    if ((j= puz->clue[k][i].jobindex) >= 0)
    {
        if (VJ || WL(puz->clue[k][i]))
            printf(" J: JOB ON %s %d ALREADY ON JOBLIST\n",
                   CLUENAME(puz->type,k),i);

        /* Increase the priority of the job, bubbling it up the heap if
         * necessary
         */

        puz->job[j].priority+= 4 + 25*bonus;
        if (puz->job[j].depth > depth) puz->job[j].depth= depth;

        while (j > 1 && puz->job[par= j/2].priority < puz->job[j].priority)
        {
            job_exchange(puz, j, par);
            j= par;
        }

        return;
    }

    /* Give higher priority to things on the edge */
    priority= abs(puz->n[k]/2 - i) + 25*bonus - 10*depth;


    if (VJ || WL(puz->clue[k][i]))
        printf(" J: JOB ON %s %d ADDED TO JOBLIST DEPTH %d PRIORITY %d\n",
               CLUENAME(puz->type,k),i,depth,priority);

    /* Bubble things down until we find the spot to insert the new key */
    j= ++puz->njob;
    while (j > 1 && puz->job[par= j/2].priority < priority)
    {
        job_move(puz, j, par);
        j= par;
    }

    /* Insert the new key */
    puz->clue[k][i].jobindex= j;
    job= &puz->job[j];
    job->priority= priority;
    job->depth= depth;
    job->dir= k;
    job->n= i;
}
Example #2
0
int line_solve(Puzzle *puz, Solution *sol, int contradicting)
{
    extern dir_t cont_dir;
    extern line_t cont_line;
    dir_t dir;
    line_t i;
    int depth;

    while (next_job(puz, &dir, &i, &depth))
    {
        nlines++;
        if ((VB && !VC) || WL(dir,i))
            printf("*** %s %d\n",CLUENAME(puz->type,dir), i);
        if (VB || WL(dir,i))
            dump_line(stdout,puz,sol,dir,i);

        if (contradicting && depth >= contradepth)
        {
            /* At max depth we just check if the line is solvable */
            line_t *pos, *bcl;
            if (!left_solve(puz, sol, dir, i, 0, &pos, &bcl))
            {
                if ((VC&&VV) || WL(dir,i))
                    printf("C: %s %d OK AT DEPTH %d\n",
                           cluename(puz->type,dir),i,depth);
            }
            else
            {
                if ((VC&&VV) || WL(dir,i))
                    printf("C: %s %d FAILED AT DEPTH %d\n",
                           cluename(puz->type,dir),i,depth);
                if (contradicting) {
                    cont_dir= dir;
                    cont_line= i;
                }
                return 0;
            }
        }
        else if (apply_lro(puz, sol, dir, i, depth + 1))
        {
            /* Found a contradiction */
            if (contradicting) {
                cont_dir= dir;
                cont_line= i;
            }
            return 0;
        }

        if (VJ)
        {
            printf("CURRENT JOBS:\n");
            dump_jobs(stdout,puz);
        }
    }
    return 1;
}
Example #3
0
void add_jobs(Puzzle *puz, Solution *sol, int except, Cell *cell,
              int depth, bit_type *old)
{
    dir_t k;
    line_t i, j;
    int lwork, rwork;

    /* While probing, we OR all bits set into our scratchpad.  These values
     * should not be probed on later during this sequence.
     */
    if (probing)
        fbit_or(propad(cell),cell->bit);

    if (!maylinesolve) return;

    for (k= 0; k < puz->nset; k++)
        if (k != except)
        {
            i= cell->line[k];
            j= cell->index[k];

            /* We only add the job only if either the saved left or right
             * solution for the line has been invalidated.
             */
            if (VL || WL(puz->clue[k][i]))
                printf ("L: CHECK OLD SOLN FOR %s %d CELL %d\n",
                        CLUENAME(puz->type,k),i,j);
            lwork= left_check(&puz->clue[k][i], j, cell->bit);
            rwork= right_check(&puz->clue[k][i], j, cell->bit);
            if (lwork || rwork)
            {
                add_job(puz, k, i, depth,
                        newedge(puz, sol->line[k][i], j, old, cell->bit) );

                if (!VJ && WL(puz->clue[k][i]))
                    dump_jobs(stdout,puz);
            }
        }
}
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;
}