Files Classes Functions Hierarchy
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
1.5.8