SEclone  storing a puzzle, permanent data, alt index

 

We continue with general classes

 

#include "h\_00d_  GG.h"                 // storing and handlin a grid 9x9 or 81

#include "h\_01a_  unp_unpf_pf_tpf.h"    // permanent characteristics cells, .....

#include "h\_00f_obbi.h"                 // viewing cells per object/pos/digit or object/digit/pos

 

Class GG is defined to store a puzzle as 81 bytes and to have the flexibility to work in it as a 9 x9 byte field or a 81 bytes field. The puzzle is always shown as a string. Byte 82 contains 0.

 

// short class to define and handle a 9x9 or 81 bytes field

// this is the classical storage for a puzzle

class GG{public:

char g [9][9],filler,*pg;  // une grille givens/assigned

 

GG(){pg=g[0]; pg[81]=0;}

inline char * Getpg() {return pg;}

inline void Copie(GG & ge) { strcpy_s(pg,82,ge.pg);}// copie 81 caractères

inline void operator =(GG&ge){ strcpy_s(pg,82,ge.pg);}

int NBlancs(){int i,n=0; for(i=0;i<81;i++) if(pg[i]=='0')n++;   return n;} 

int Nfix(){int i,n=0; for(i=0;i<81;i++) if(pg[i]-'0')n++;   return n;}

void Image(char * lib);

};

 

 

void GG::Image(char * lib)

 {E$.E(lib); E$.Enl(); char wc[10];

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

   {strncpy_s(wc,10,g[i],9);wc[9]=0;E$.E(i+1);E$.E("=");E$.E(wc); E$.Enl();}}

 

 

 

 

 

The file unp…. Contains all classes with “permanent data”, prepared one for ever at the start;

 

P81F has permanent data for a cell

TP81F is the table collecting the 81 cells

DIVF contains other permanent data as the 9x9 index and the 81 bit image for rows/col/boxes

 

 

 

 

//small class containing the permanent data for a cell

class P81F  

 {public:

   USHORT i8,   // cell index (0;80)

          el,      // row (0;8)

          pl,      // column

          eb,      // box 

          pb,      // relative position in the box

          pi[20];  //pi is the list of the  20 cells controled by a cell

   char pt[5];  // printing string

   ZINFL z;     // same as pi list in a bit field

 

   void init(USHORT ie){i8=ie; el=i$.Div9(ie);

                        pl=ie-9*el;   eb=i$.Boite(el,pl); pb=i$.PosBoite(el,pl);

                        strcpy_s(pt,5,"r c "); 

                                          pt[1]=(char)(el+'1');pt[3]=(char)(pl+'1');}

   void Initpi()  {int it=0;for (int i=0;i<81;i++) if(z.On(i))  pi[it++]=i; } 

 

   int ObjCommun(P81F* p8){return((el==p8->el)||(pl==p8->pl)||  eb==p8->eb);}

 

   int BugParite(int ch);  // utilise aztob

};

 

// and the table containing the fix data for the 81 cells

class TP81F

public:

   P81F t81f[81]; // constructor making all initialisations

   TP81F()  {int i,j; for(i=0;i<81;i++) t81f[i].init(i);

             for(i=0;i<81;i++)      // initial zone influence

                 {ZINFL z; z.Init();

                 for(j=0;j<81;j++) if((i-j)&& t81f[i].ObjCommun(&t81f[j]))z.Set(j);

                       t81f[i].z=z;    t81f[i].Initpi();} }

 

   USHORT GetLigCol(USHORT p1,USHORT p2)  // only if is lig or col (UR)

                   {if(t81f[p1].el==t81f[p2].el) return t81f[p1].el;

                    return (t81f[p1].pl+9);}

}tp81f;

 

P81F * t81f=tp81f.t81f;                    //pointer to speed up the process  

 

 

 

 

// an object is here a row (0,8) a column (9 17) or a box (18 26)

 

 

class DIVF  //various vectors to handle objects and

{public:

  USHORT el81[27][9]; // object to cell (0 80)

  ZINFL elz81[27];    // same as a bit field

  DIVF()   // constructor making initialisations

      { for(int r=0;r<9;r++) for(int c=0;c<9;c++)

         {int p=i$.Pos(r,c); el81[r][c]=p; el81[c+9][r]=p;

         int eb=i$.Boite(r,c),pb=i$.PosBoite(r,c); el81[eb+18][pb]=p;}

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

           {ZINFL z; z.Init(); for(int j=0;j<9;j++) z.Set(el81[i][j]);  elz81[i]=z;} 

       }

  int IsObjetI (ZINFL &ze,int i)      {return (ze.EstDans(elz81[i])); };

  int IsObjet(ZINFL &ze)

      {for(int i=0;i<27;i++) if(IsObjetI(ze,i)) return 1;  return 0;} 

  int IsBox(ZINFL &ze) {for (int i=18;i<27;i++)

                           if (IsObjetI (ze,i)) return i; return 0;}

 

  int IsObjet(USHORT p1,USHORT p2) {ZINFL z(p1,p2); return IsObjet(z);}

  int IsAutreObjet(ZINFL &ze,int obje, int &objs)

      {for(int i=0;i<27;i++)

         {if(i==obje) continue; if(IsObjetI(ze,i)) {objs=i;return 1;  }  }

       return 0;}

  int N_Fixes(char * pg,int el)

     {int n=0; for(int i=0;i<9;i++) if(pg[el81[el][i]]-'0') n++;return n;}

}divf;

 

Alternative  index

 

OBBI is an entry locate some 9 bits fields

 

Either the location of a digit in a row/col/box

Or the  digits located in relative position x in the row/col/box.

 

The elementary class contains a 9 bits field and the count of corresponding digits/cells.

 

That index is updated at the start of a new solving cycle.

 

The file “obbi.h” contains also the small class UNP containing the non permanent data for a cell, and, more specifically, the candidate bit field and the number of candidates used to update the alternative index.

 

Here we have a separate file containing the updating of the index. The table of cells, used in that task is not yet defined. That routine (Genere() )  has been added here.

 

  // small class containing non permanent data for a cell

class UNP // la base des candidats d'un point

{public:  USHORT ncand,typ;  CB9CH cand; //0 free  2 given  1 assigned

  void Init(){ncand=9;cand.f=0x1ff;typ=0;}

  inline void Fixer(USHORT i){ncand=1;cand.f=(1<<i);}  

  inline void Fixer(USHORT t,USHORT i){typ=t;Fixer(i);}

  inline int Clear (int i)

      {if(cand.On(i)){ ncand--; cand.f^=(1<<i); return 1;}

       return 0;}

  USHORT GetCand(){for(USHORT i=0;i<9;i++)

                    if(cand.On(i)) return i;return 0;}

  };

 

 

// several small classes to work on a view per object/pos/digit

//                                         or  object/digit/pos

// updated at the beginning of a new cycle

 

// one cell; digits and number of digits

class OBBITD    {public: CB9CH b;  USHORT n;

                 void Raz(){b.f=0;n=0;};

                 void Set(int i) {b.Set(i);n++;};

                 void Genpo(UNP p8){ n=p8.ncand;b=p8.cand;   };

                 };

// vector for 9 cells or digits

class OBBIEL {public: OBBITD eld [9];

               int tiroir(CB9CH fd,int iold,int irang);

               };

// grouping the 27 rows/cols/boxes

class TOBBIT   {public: OBBIEL el[27];  };

 

// main class defined once updated once per cycle

class ZTOB {public: TOBBIT tpobit,  tchbit;

            void Genere();  // update

           }aztob;

 

 

 

void ZTOB::Genere()

{ int i,j; for(i=0;i<81;i++)   // on charge tpobit

 {P81F w=t81f[i]; UNP x=T81t[i].v;

  tpobit.el[w.el].eld[w.pl].Genpo (x);

  tpobit.el[w.pl+9].eld[w.el].Genpo (x);

  tpobit.el[w.eb+18].eld[w.pb].Genpo (x);}

  // on génère tch a partir de tpo

 for(i=0;i<27;i++)  // les 27 groupes

  {for(j =0;j<9;j++) tchbit.el[i].eld[j].Raz();

       for(j =0;j<9;j++) for(int k =0;k<9;k++)

         if(tpobit.el[i].eld[j].b.On(k)) tchbit.el[i].eld[k].Set(j);   }

 

 }