int findAllPlain(int x[9][9]){ int possible_mask[9]; int num_possible; int i,j,k; int num_found; int rounds=0; do { num_found=0; //printf("Round %d --------\n", rounds); for(i=0; i<9; i++){ for(j=0; j<9; j++){ //printf("Checking <%d,%d>==%d\n", i,j,x[i][j]); if(x[i][j] != 0) continue; num_possible = checkspot(x, i,j,possible_mask); //printf("[%d,%d] Num Possible=%d\t", i,j, num_possible); //for(k=0; k<9; k++) // if(possible_mask[k]) printf(" %d",k+1); //printf("\n"); if(num_possible==1){ for(k=0; possible_mask[k]==0; k++); //printf("[%d,%d] Found===> %d\n", i,j, k+1); x[i][j] = k+1; num_found++; } else if(num_possible>1) { k = checkElim(x,i,j,possible_mask); if(k>=0){ //printf("XXXXXXXXXXXX Found Elim at %d,%d => %d\n", i,j,k+1); x[i][j] = k+1; num_found++; } } } } rounds++; } while(num_found>0); int num_empty=0; for(i=0; i<9; i++) for(j=0; j<9; j++) if(x[i][j]==0) num_empty++; //printf("Did %d rounds, Empty=%d\n", rounds, num_empty); return num_empty; }
int pickNextGuess_least(int x[9][9], char *ignore_guess_mask){ int i,j; int possible_mask[9]; int least_num=9; int least_id=-1; int tmp_num; for(i=0; i<9; i++) for(j=0; j<9; j++){ if((x[i][j]==0)&&(ignore_guess_mask[i*9+j]==0)){ tmp_num = checkspot(x, i,j, possible_mask); if(tmp_num < least_num){ least_num = tmp_num; least_id = (i*9)+j; } } } return least_id; }
extern void marksources(void) /* find and mark source objects */ { int foundsource = 0; int i; register OBJREC *o, *m; register int ns; /* initialize dispatch table */ initstypes(); /* find direct sources */ for (i = 0; i < nsceneobjs; i++) { o = objptr(i); if (!issurface(o->otype) || o->omod == OVOID) continue; /* find material */ m = findmaterial(objptr(o->omod)); if (m == NULL) continue; if (m->otype == MAT_CLIP) { markclip(m); /* special case for antimatter */ continue; } if (!islight(m->otype)) continue; /* not source modifier */ if (m->oargs.nfargs != (m->otype == MAT_GLOW ? 4 : m->otype == MAT_SPOT ? 7 : 3)) objerror(m, USER, "bad # arguments"); if (m->oargs.farg[0] <= FTINY && m->oargs.farg[1] <= FTINY && m->oargs.farg[2] <= FTINY) continue; /* don't bother */ if (m->otype == MAT_GLOW && o->otype != OBJ_SOURCE && m->oargs.farg[3] <= FTINY) { foundsource += (ambounce > 0); continue; /* don't track these */ } if (sfun[o->otype].of == NULL || sfun[o->otype].of->setsrc == NULL) objerror(o, USER, "illegal material"); if ((ns = newsource()) < 0) goto memerr; setsource(&source[ns], o); if (m->otype == MAT_GLOW) { source[ns].sflags |= SPROX; source[ns].sl.prox = m->oargs.farg[3]; if (source[ns].sflags & SDISTANT) { source[ns].sflags |= SSKIP; foundsource += (ambounce > 0); } } else if (m->otype == MAT_SPOT) { source[ns].sflags |= SSPOT; if ((source[ns].sl.s = makespot(m)) == NULL) goto memerr; if (source[ns].sflags & SFLAT && !checkspot(source[ns].sl.s,source[ns].snorm)) { objerror(o, WARNING, "invalid spotlight direction"); source[ns].sflags |= SSKIP; } } #if SHADCACHE initobscache(ns); #endif foundsource += !(source[ns].sflags & SSKIP); } if (!foundsource) { error(WARNING, "no light sources found"); return; } markvirtuals(); /* find and add virtual sources */ /* allocate our contribution arrays */ maxcntr = nsources + MAXSPART; /* start with this many */ srccnt = (CONTRIB *)malloc(maxcntr*sizeof(CONTRIB)); cntord = (CNTPTR *)malloc(maxcntr*sizeof(CNTPTR)); if ((srccnt == NULL) | (cntord == NULL)) goto memerr; return; memerr: error(SYSTEM, "out of memory in marksources"); }
int iterate(int x[9][9], int guess_depth, int guesses[81]){ int num_left; int y[9][9]; int possible[9]; int i,j,k; static int num_rounds=0; char ignore_guess_mask[81]; //Mark off ones we've tried already int next_guess_spot; //Ignore mask is just for this depth memset(ignore_guess_mask, 0, 81*sizeof(char)); num_rounds++; if(!(num_rounds & 0x0FFF)){ printf("::New Iterate, Depth=%d:", guess_depth); for(i=0;i<81; i++) if(guesses[i]) printf("%d=%d ",i,guesses[i]); printf("\n"); } num_left = findAllPlain(x); if(num_left==0){ // and valid struct timeval stop_time; gettimeofday(&stop_time,NULL); printf("Time=%d s Algorithm=%s\n", stop_time.tv_sec - start_time.tv_sec, guess_alg_names[GUESS_TYPE]); printf("Guess depth=%d guesses:",guess_depth); for(i=0;i<81; i++) if(guesses[i]) printf("%d=%d ",i,guesses[i]); printf("\n"); dump(x); exit(0); } next_guess_spot = pickNextGuess(x, ignore_guess_mask, guesses); while(next_guess_spot>=0){ i=next_guess_spot/9; j=next_guess_spot%9; assert(x[i][j]==0); checkspot(x,i,j,possible); for(k=0;k<9;k++){ if(!possible[k])continue; memcpy(y,x,9*9*sizeof(int)); y[i][j] = k+1; guesses[i*9+j]=k+1; iterate(y,guess_depth+1,guesses); } guesses[i*9+j]=0; next_guess_spot = pickNextGuess(x,ignore_guess_mask, guesses); } return -1; }
int checkElim(int x[9][9], int row, int col, int *outter_possible_mask){ int v; int rstart=row/3; int cstart=col/3; int inner_possible_mask[9]; int is_unique; int i,j; for(v=0; v<9; v++){ if(!outter_possible_mask[v]) continue; is_unique=1; //Check within our square to see if nobody else is using this for(i=rstart*3; i<rstart*3+3; i++) for(j=cstart*3; j<cstart*3+3; j++){ //printf(" xcheck %d,%d for val %d\n",i,j, v+1); if(!((row==i)&&(col==j))&&(x[i][j]==0)){ checkspot(x, i,j,inner_possible_mask); if(inner_possible_mask[v]) { //printf(" xcheck square killed\n"); is_unique=0; i=j=9; } } } if(is_unique) return v; int k; //Check row to see if unique is_unique=1; for(i=0; i<9; i++){ if((i==row) || (x[i][col]!=0)) continue; checkspot(x,i,col,inner_possible_mask); //printf(" IR for [%d,%d] vals are ", i,col); //for(k=0;k<9;k++) // if(inner_possible_mask[k]) printf(" %d", k+1); //printf("\n"); if(inner_possible_mask[v]){ //printf(" xcheck row killed\n"); is_unique=0; i=j=9; } } if(is_unique) return v; //Check col to see if unique is_unique=1; for(j=0; j<9; j++){ if((j==col)||(x[row][j]!=0)) continue; checkspot(x,row,j,inner_possible_mask); if(inner_possible_mask[v]){ //printf(" xcheck col killed\n"); is_unique=0; i=j=9; } } if(is_unique) return v; } return -1; }