proj home

Files   Classes   Functions   Hierarchy  

mazematrixD2.h

Go to the documentation of this file.
00001 #ifndef MAZEMATRIXD2_H
00002 #define MAZEMATRIXD2_H
00003 
00004 #include <cassert>
00005 #include <vector>
00006 using namespace std;
00007 
00008 #include <cellD2.h>
00009 #include <print.h>
00010 #include <stringconvert.h>
00011 #include <stringtagparser.h>
00012 
00037 template< typename T >
00038 class mazematrixD2
00039 {
00040 public:
00041 
00043   uint dim[3];
00044 
00046   void dimset(uintc rows, uintc columns);
00047 
00049   vector< cellD2<T> > vi;
00050 
00052   mazematrixD2();
00053 
00055   mazematrixD2(uintc rows, uintc columns);
00056 
00058   uintc add();
00059 
00061   T neib(T id, uintc k) const;
00062 
00064   void link( T id, uintc k, T id2);
00065 
00067   void link(T id, uintc k, T id2, uintc k2);
00068 
00070   boolc valid() const;
00071 
00073   cellD2<T> & access(uintc r, uintc c) 
00074     { return vi[c+r*dim[0]+1]; }
00075 
00077   void access(bool & res, cellD2<T>& x, uintc r, uintc c);
00078 
00080   void move(bool & res, T& k2, uintc mv, T const k) const;
00081 
00083   void neighboursunvisited( vector<T> & v, T const k);
00084 
00086   void linkadjacent(bool & res, T const id1, T const id2);
00087 
00089   operator stringc () const;
00090 
00092   void serializeInverse(stringc & str);
00093 
00094 };
00095 
00096 
00097 //----------------------------------------------------------
00098 // Implementation
00099 
00100 
00101 template< typename T >
00102 void mazematrixD2<T>::access(bool & res, cellD2<T>& x, uintc r, uintc c)
00103 {
00104   res=false;
00105   T k=c+r*dim[0]+1;
00106   if (k < dim[2]+1)
00107   {
00108     if (k!=0)
00109     {
00110       x=vi[k];
00111       res=true;
00112     }
00113   }
00114 }
00115 
00116 template< typename T >
00117 void mazematrixD2<T>::dimset(uintc rows, uintc columns)
00118 {
00119   dim[0]=rows;
00120   dim[1]=columns;
00121   dim[2]=rows*columns;
00122 
00123   vi.resize(rows*columns+1);
00124   for (T i=0; i<vi.size(); ++i)
00125     vi[i].id=i;
00126 }
00127 
00128 
00129 template< typename T >
00130 uintc mazematrixD2<T>::add()  
00131 {
00132   assert(dim[0]*dim[1]!=0); // dimset must be called
00133 
00134   uint k=vi.size();
00135   cellD2<T> x;
00136   x.id=k;
00137   vi.push_back(x);
00138 
00139   return k;
00140 }
00141 
00142 
00143 template< typename T >
00144 mazematrixD2<T>::mazematrixD2(uintc rows, uintc columns)
00145 {
00146   dimset(rows,columns);
00147 }
00148 
00149 
00150 template< typename T >
00151 mazematrixD2<T>::mazematrixD2()
00152 {
00153   dim[0]=0;
00154   dim[1]=0;
00155   dim[2]=0;
00156 }
00157 
00158 template< typename T >
00159 T mazematrixD2<T>::neib(T id, uintc k) const
00160 {
00161   assert(id!=0);
00162   assert(id<=dim[2]);
00163   assert(k<4);
00164 
00165   uint n=dim[1];
00166 
00167   // Up.
00168   if (k==0)
00169   {
00170     if (id<=n)
00171       return 0;
00172     return id-n;
00173   }
00174 
00175   // Down.
00176   if (k==2)
00177   {
00178     if (id+n>dim[2])
00179       return 0;
00180     return id+n;
00181   }
00182 
00183   // Right.
00184   if (k==1)
00185   {
00186     if ((id%n)==0)
00187       return 0;
00188 
00189     return id+1;
00190   }
00191  
00192   // Left.
00193   if (k==3)
00194   {
00195     if (((id+n-1)%n)==0)
00196       return 0;
00197 
00198     return id-1;
00199   }
00200 
00201   assert(false);
00202 
00203   return 0;
00204 }
00205 
00206 template< typename T >
00207 void mazematrixD2<T>::link( T id, uintc k, T id2)
00208 {
00209   assert(dim[0]*dim[1]!=0); // dimset must be called
00210   assert(k<4);
00211   assert(id!=0);
00212   assert(id2!=0);
00213   //assert(id<=dim[2]);
00214   //assert(id2<=dim[2]);
00215 
00216   uint k2=(k+2)%4;
00217 
00218   vi[id].ni[k] = id2;
00219   vi[id2].ni[k2] = id;
00220 }
00221 
00222 
00223 template< typename T >
00224 void mazematrixD2<T>::link( T id, uintc k, T id2, uintc k2)
00225 {
00226   assert(dim[0]*dim[1]!=0); // dimset must be called
00227   assert(k<4);
00228   assert(k2<4);
00229   assert(id!=0);
00230   assert(id2!=0);
00231 
00232   vi[id].ni[k] = id2;
00233   vi[id2].ni[k2] = id;
00234 }
00235 
00236 template< typename T >
00237 boolc mazematrixD2<T>::valid() const
00238 {
00239   assert(dim[0]*dim[1]!=0); // dimset must be called
00240   if (dim[0]*dim[1]==0)
00241     return false;
00242 
00243   uint imax=vi.size();
00244   T nb;
00245   T nb2local;
00246   for (uint i=1; i<imax; ++i)
00247   {
00248 //    cout << "error: " << (string)vi[i] << endl;
00249 
00250     assert(!(vi[i].id!=i));
00251     if (vi[i].id!=i)
00252       return false;
00253 
00254     for (uint k=0; k<4; ++k)
00255     {
00256 //cout << SHOW(k) << endl;
00257       nb=vi[i].ni[k];
00258 //cout << SHOW(nb) << endl;
00259       if (nb!=0)
00260       {
00261         assert(!(nb>=imax));
00262         if (nb>=imax)
00263           return false;
00264 
00265         nb2local = vi[nb].niInv(i);
00266         assert(!(nb2local==4));
00267         if (nb2local==4)
00268           return false;
00269         assert(!(vi[nb].ni[nb2local]!=i));
00270         if (vi[nb].ni[nb2local]!=i)
00271           return false;
00272       }
00273     }
00274 
00275   } 
00276 
00277   return true;
00278 }
00279 
00280 template< typename T >
00281 void mazematrixD2<T>::move
00282 (
00283   bool & res, 
00284   T& k2, 
00285   uintc mv, 
00286   T const k
00287 ) const
00288 {
00289   uintc m=dim[0];
00290   uintc n=dim[1];
00291 
00292   assert(mv<4);
00293 
00294   if (mv==3)
00295   {
00296     res=(((k-1)%n)!=0);
00297     k2=k-1;
00298     return;
00299   }
00300 
00301   if (mv==1)
00302   {
00303     res=((k%n)!=0);
00304     k2=k+1;
00305     return;
00306   }
00307 
00308   if (mv==0)
00309   {
00310     res=(k>n);
00311     k2=k-n;
00312     return;
00313   }
00314 
00315   if (mv==2)
00316   {
00317     res=((k+n-1)<m*n);
00318     k2=k+n;
00319     return;
00320   }
00321 
00322 
00323 /*
00324 
00325   // Shift so counting from 0.
00326   // I could easily put the substitutions in, but
00327   // that would make the code less clear.
00328   T w = k-1;
00329   
00330   if (mv==3)
00331   {
00332     res=((w%n)!=0);
00333     k2=w-1;
00334     ++k2;
00335     return;
00336   }
00337 
00338   if (mv==1)
00339   {
00340     res=(((w+n-1)%n)!=0);
00341     k2=w+1;
00342     ++k2;
00343     return;
00344   }
00345 
00346   if (mv==0)
00347   {
00348     res=(w>=n);
00349     k2=w-n;
00350     ++k2;
00351     return;
00352   }
00353 
00354   if (mv==2)
00355   {
00356     res=((w+n)<m*n);
00357     k2=w+n;
00358     ++k2;
00359     return;
00360   }
00361 */
00362 
00363 
00364 }
00365 
00366 template< typename T >
00367 void mazematrixD2<T>::neighboursunvisited
00368 ( 
00369   vector<T> & v, 
00370   T const k
00371 )
00372 {
00373 //cout << SHOW(k) << endl;
00374   v.clear();
00375   bool res;
00376   T k2;
00377   for (uint i=0; i<4; ++i)
00378   {
00379     move(res,k2,i,k);
00380 //cout << SHOW(k2) << endl;
00381     if (res)
00382     {
00383       if (vi[k2].unvisited())
00384         v.push_back(k2);
00385     }
00386   }
00387 }
00388 
00389 template< typename T >
00390 void mazematrixD2<T>::linkadjacent
00391 (
00392   bool & res, 
00393   T const id1, 
00394   T const id2
00395 )
00396 {
00397   res=false;
00398 
00399   if (id1==id2)
00400     return;
00401 
00402   T a;
00403   T b;
00404 
00405   if (id1<id2)
00406     { a=id1; b=id2; }
00407   else
00408     { a=id2; b=id1; };
00409 
00410   // Horizontal linkage
00411   if (a+1==b)
00412   {
00413     link(a,1,b,3);  
00414     res=true;
00415     return;
00416   }
00417 
00418   // Vertical linkage
00419   if (a+dim[1]==b)
00420   {
00421     link(a,2,b,0);
00422     res=true;
00423     return;
00424   }
00425 }
00426 
00427 
00428 template< typename T >
00429 mazematrixD2<T>::operator stringc () const
00430 {
00431   string s1="<mazematrixD2>\n";
00432   s1 += "<dim>";
00433   s1 += stringto(dim[0]);
00434   s1 += " ";
00435   s1 += stringto(dim[1]);
00436   s1 += "</dim>\n";
00437   s1 += stringtag(vi.size(),"visize");
00438   s1 += "<vi>\n";
00439   for (uint i=0; i<vi.size(); ++i)
00440   {
00441     s1 += (stringc)vi[i];
00442     s1 += " \n";
00443   }
00444   
00445   s1 += "</vi>\n";
00446   s1 += "</mazematrixD2>\n";
00447   
00448   return s1;
00449 }
00450 
00451 
00452 template< typename T >
00453 void mazematrixD2<T>::serializeInverse(stringc & str)
00454 {
00455   string s2(stringtagparser(str).data("mazematrixD2"));
00456 
00457   { 
00458     stringstream ss(stringtagparser(s2).data("dim")); 
00459     ss >> dim[0] >> dim[1];
00460     dim[2]=dim[0]*dim[1];
00461   }
00462 
00463   T n;
00464   stringfrom(n,stringtagparser(s2).data("visize"));
00465   {
00466     vi.resize(n);
00467     stringstream ss(stringtagparser(s2).data("vi"));
00468     for (T i=0; i<n; ++i)
00469     {
00470       vi[i].serializeInverse(ss); 
00471     }
00472   }
00473 
00474 }
00475 
00476 
00477 #endif
00478 
00479 

Generated on Fri Mar 4 00:49:29 2011 for Chelton Evans Source by  doxygen 1.5.8