SEclone  solving class jdk

 

The last general and key class to solve a puzzle is JDK, a class holding among others the table of cells and the bit fields of the rookeries.

 

This also the place where

 

Is located the main routine chaining the solving steps

Most of the routines for a given solving technique start

all eliminations are validated toward the solution

assignments are looked for and done

A milestone is updated to locate precisely a differed action in a print

 

Cleaning in that class is far from being done. Moreover, some routines are added to investigate solving techniques not yet coded.

 

I give here a version truncated to BUGs as last solving technique.

I also erased some data not yet used in the first phase of the coding

The version in the zip file will be slightly different

 

The main data are

 

gg                           is the puzzle stored, including assignments

tp8N  tp8N_cop     the table of cells and a copie never touched during a cycle

c  c_cop                 same for rookeries

csol                       the final solution expressed in rookeries mode

zactif                     cells still not assigned at the start of a cycle

elza81                   same for each row column or box

 

fix fixt                 tables used in the process locatinf cells to assign

 

The main process is Traite(). It will be studied in the next page;

Here are only shown the other general routines of the here below reduced class

 

#include "h\_03a_jdk.h"                  // general class to solve a puzzle

 

 

class JDK{ public:

 

    GG gg;           // char *gn; // aussi index 0 80

 

    TP81 tp8N,tp8N_cop; 

    ZINFL c[9],c_cop[9]; // grille globale et par chiffre

 

    ZINFL zactif,elza81[27],csol[9];   //  mode ZINFL  puis ZINFL

 

    int cycle, coup,coupMM,couprem, cas,fixes,ecrit,compte;

 

    char fix[81],fixt[81],*solution;

 

    USHORT nfix,nmin,p81min;

 

    JDK();

    void Initial();

    void cInit(int un=0);

    void Copie_T_c();

    void cFixer(int ich,int i8);

    void cReport();  

    void TReport();  

    void Actifs();

    void Influence (ZINFL &zd,ZINFL zo);

    ZINFL Points(int el,CB9CH po);

    int CheckChange(int i, int ch);

    int ChangeSauf(int elem,CB9CH pos,CB9CH chiffres );

    int Keep(int elem,CB9CH pos,CB9CH chiffres );

    int Keep(int ch,ZINFL zk); // éliminer ailleurs en objets contenant

    int Keep(int ch,USHORT p1,USHORT p2); // éliminer ailleurs de deux points

    int NonFixesEl(int e);

    void FixerAdd(int i,char c,int elt)

                {fix[i]=c;  fixt[i]=(char)elt; nfix++;};

    int Check();

    int Recale();             

    int Traite();

    int Directs();            

    int FaitDirects(int type);

    int FaitGoA(int i8,char c1,char c2)

       {int ir=FaitGo(i8,c1,c2);cReport();return ir;}

 

    int TraiteLocked(int rating);  // start for locked in row,cil,box

    int TraiteLocked2(int eld,int elf); // detail for ratings 2.6  2.8

 

    void PKInit(){couprem=0;pointK.Init();}

    void PointK();

private:

       int FaitGo(int i8,char c1,char c2);

   }jdk;

 

 

The subroutines often called are located in the file

 

#include "c\_03a_  jdk.cpp"

 

JDK::JDK()

{solution=un_jeu.ggf.pg; 

 T81=&tp8N;T81C=&tp8N_cop;T81t=T81->t81;T81tc=T81C->t81;}

 

void JDK::Initial()

{// tzg.PG54Init();         en attente      <========================<<<<<<<<<

}

void JDK::Copie_T_c()

{tp8N_cop=tp8N;for(int i=0;i<9;i++) c_cop[i]=c[i];}

 

void JDK::Actifs()

{zactif.Init();T81->Actifs(zactif);

for(int i=0;i<27;i++)elza81[i]=divf.elz81[i]&zactif;}

 

void  JDK::cInit(int un)

{for (int i=0;i<9;i++) if(un)c[i].InitUn(); else c[i].Init();}

 

void JDK::cFixer(int ich,int i8)

 {for (int i=0;i<9;i++) c[i].Clear(i8); // pas de candidat ici

  c[ich].Clear(t81f[i8].z); }   // ni en zone influence

 

void JDK::cReport()     // on charge cand de ztzch

 {for(int i8=0;i8<81;i8++)

  {P81 *p8=&tp8N.t81[i8]; if (p8->v.typ) continue;

       p8->v.ncand=0; p8->v.cand.f=0;   p8->scand[0]=0;

       for (int i=0;i<9;i++)        if(c[i].On(i8)) p8->v.cand.Set(i);

       p8->v.ncand=p8->v.cand.CountEtString(p8->scand);

       strcpy_s(p8->colcand,10,p8->scand );

  }}

 

void JDK::TReport()     // on charge c de table en mode depart impose

 {for(int i=0;i<9;i++) c[i].Init();

 for(int i8=0;i8<81;i8++)

  {P81 *p8=&tp8N.t81[i8]; if (p8->v.typ) continue;

   for (int i=0;i<9;i++)if(p8->v.cand.On(i)) c[i].Set(i8);

   p8->v.ncand=p8->v.cand.CountEtString(p8->scand);

       strcpy_s(p8->colcand,10,p8->scand );

  }}

 

 

int JDK::Recale()

{ //cReport();

 nfix=0;

 for(int i=0; i<81;i++)  {fix[i]='0'; if(T81t[i].v.ncand==0) return 0;}

  aztob.Genere();  

  for(int i=0; i<27;i++) for (int j=0;j<9;j++)

     if(aztob.tchbit.el[i].eld[j].n==0)   return 0;

return 1;}

 

int JDK::Directs() //en tete appliquer regle de base

{ int ir=0, i;

  for(i=0;i<81;i++)if((!T81t[i].v.typ)&&(T81t[i].v.ncand==1) )   // case 1 candidat

         {FixerAdd(i,T81t[i].scand[0],3); ir=1;}

  for(i=0; i<27;i++)for(int j=0; j<9;j++)   // chiffre une place

  if(aztob.tchbit.el[i].eld[j].n==1)

  {int k=aztob.tchbit.el[i].eld[j].b.First(),i8=divf.el81[i][k];

    if(!T81t[i8].v.typ)      { FixerAdd(i8,(char)('1'+j),i/9); ir=1;}}

return ir;}

 

// doing assignments matching expected rating if any

//    LastCell=10,            last cell in row column box

//    SingleBlock=12,    single box

//    Single_R_C=15,     single row column

//    NakedSingle=23,  cell one candidate

 

int   JDK::FaitDirects(int rating)

{if(aigstop) return 1;

 int ir=0;

 for(int i=0;i<81;i++)

   { char c1= fix[i], c2= fixt[i];

     if( c1-'0')     // donc fixée

      { // filter on rating expected

               int ok=0; P81F p=t81f[i];

               switch(rating)

               {case 10: if(    (divf.N_Fixes(gg.pg,p.el)==8)

                             || (divf.N_Fixes(gg.pg,p.pl+9)==8)

                             || (divf.N_Fixes(gg.pg,p.eb+18)==8) ) ok=1;

                         break;

                case 12: if(aztob.tchbit.el[p.eb+18].eld[c1-'1'].n==1) ok=10;

                            break;

                case 15: if(aztob.tchbit.el[p.el].eld[c1-'1'].n==1) ok=1;

                            if(aztob.tchbit.el[p.pl+9].eld[c1-'1'].n==1) ok=1;

                            break;

                case 23: if( (gg.pg[i]=='0') && (T81t[i].v.ncand==1) ) ok=1;

                            break;

               }

               if(ok) ir+=FaitGo(i,c1,c2);

          }

      }

  E$.Enl();; 

  if(ir)cReport(); return ir;}

 

 

int JDK::FaitGo(int i,char c1,char c2) // function also called if single forced

{E$.E(++o$.assigned);

 E$.E(" ");E$.E(t81f[i].pt);E$.E("="); E$.E(c1);E$.E(" ");

 if(c2<4)E$.Enl(orig1[c2]);   else E$.Enl(" assigned");

 if((un_jeu.ggf.pg[i]-c1) && (!aigstop)) // validite  fixation

     {aigstop=1;  E$.E( "FIXATION INVALIDE"); return 0;}

 T81->Fixer(c1-'1',i,1);gg.pg[i]=c1;

 return 1;}

 

//----                     supprimer ch en elem sauf  pos

int JDK::ChangeSauf(int elem,CB9CH pos,CB9CH chiffres )

{int ir=0; for(int i=0;i<9;i++)

  {if(pos.On(i)) continue;  ir+=T81t[divf.el81[elem][i]].Change(chiffres) ; }

return ir; }

 

//----                     garder  ch en elem   pos

int JDK::Keep(int elem,CB9CH pos,CB9CH chiffres )

{int ir=0; for(int i=0;i<9;i++)

  {if(pos.On(i)) ir+=T81t[divf.el81[elem][i]].Keep(chiffres) ; }

return ir; }

 

//------                  on a un ou sature objet

int JDK::Keep(int ch1,ZINFL zk)

{int ir=0; // on cherche les objets contenant

 for(int il=0;il<27;il++) if(divf.IsObjetI(zk,il))

   {ZINFL ze=divf.elz81[il]^zk; ze=ze&c[ch1];

    if(ze.NonNul()){ir+= T81->Clear(ze,ch1);} }

return ir;}

 

//------                  ou simple deux points quelconques

int JDK::Keep(int ch1,USHORT p1,USHORT p2)

{ZINFL ze=t81f[p1].z & t81f[p2].z & c[ch1];

if(ze.NonNul())return T81->Clear(ze,ch1);return 0;}

 

 

//---------

int JDK::NonFixesEl(int el)

{int n=0; for(int i=0;i<9;i++) if(gg.pg[divf.el81[el][i]]=='0')n++;

return n;}

 

//--------                             verif au depart jeu correct

int JDK::Check()

{ CB9CH c[27]; int i; for(i=0;i<27;i++) c[i].f=0;

  for(i=0;i<81;i++) { int w=gg.pg[i]; P81F w8=t81f[i]; // t8N.t81[i].ncand=0;

                     if((w<'1') || (w>'9')) continue;      w-='1';

                     if(c[w8.el].On(w)) return 0; c[w8.el].Set(w);

                     if(c[w8.pl+9].On(w)) return 0; c[w8.pl+9].Set(w);

                     if(c[w8.eb+18].On(w)) return 0; c[w8.eb+18].Set(w);}

return 1;}

 

int JDK::CheckChange(int i, int ch)

{if(aigstop) return 1; if(solution[i]-(ch+'1'))  return 0;

aigstop=1; E$.E( "ELIMINATION INVALIDE ");E$.E(ch+1);E$.Enl(t81f[i].pt);

//T81->Candidats();zl.Image();zpln.ListeMarques();

//tac.Liste(); zcx.ListeLiens();

return 1;}

 

 void JDK::PointK()

 { couprem++; E$.E( "CREM=" );E$.E(couprem );}

 void JDK::UsePK(USHORT i)

 { E$.E(" UREM=");E$.E(i);E$.Enl(); if(i<=couprem )  pointK.Set(i);}