00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __ASSEMBLY_H__
00022 #define __ASSEMBLY_H__
00023
00024 #include "bt_assert.h"
00025 #include "symmetries.h"
00026 #include "gridtype.h"
00027
00028 #include <vector>
00029
00030
00031 #define UNPLACED_TRANS 0xff
00032
00033 class problem_c;
00034 class voxel_c;
00035 class xmlWriter_c;
00036 class xmlParser_c;
00037
00045 class placement_c {
00046
00047 public:
00048
00052 unsigned char transformation;
00053
00055 int xpos, ypos, zpos;
00056
00058 placement_c(unsigned char tran, int x, int y, int z) : transformation(tran), xpos(x), ypos(y), zpos(z) {}
00060 placement_c(const placement_c * orig) : transformation(orig->transformation), xpos(orig->xpos), ypos(orig->ypos), zpos(orig->zpos) {}
00062 placement_c(const placement_c & orig) : transformation(orig.transformation), xpos(orig.xpos), ypos(orig.ypos), zpos(orig.zpos) {}
00063
00065 int getX(void) const { return xpos; }
00067 int getY(void) const { return ypos; }
00069 int getZ(void) const { return zpos; }
00071 unsigned char getTransformation(void) const { return transformation; }
00072
00074 bool operator == (const placement_c & b) const {
00075 return ((transformation == b.transformation) &&
00076 (xpos == b.xpos) && (ypos == b.ypos) && (zpos == b.zpos));
00077 }
00078
00080 placement_c & operator = (const placement_c & b) {
00081 transformation = b.transformation;
00082 xpos = b.xpos;
00083 ypos = b.ypos;
00084 zpos = b.zpos;
00085 return *this;
00086 }
00087
00089 bool operator < (const placement_c & b) const {
00090 if (transformation < b.transformation) return true;
00091 if (transformation > b.transformation) return false;
00092
00093 if (xpos < b.xpos) return true;
00094 if (xpos > b.xpos) return false;
00095
00096 if (ypos < b.ypos) return true;
00097 if (ypos > b.ypos) return false;
00098
00099 if (zpos < b.zpos) return true;
00100 if (zpos > b.zpos) return false;
00101
00102 return false;
00103 }
00104 };
00105
00111 class mirrorInfo_c {
00112
00114 typedef struct {
00115 unsigned int pc1;
00116 unsigned int pc2;
00117
00118 unsigned char trans;
00119 } entry;
00120
00122 std::vector<entry> entries;
00123
00124 public:
00125
00126 mirrorInfo_c(void) {};
00127
00132 void addPieces(unsigned int p1, unsigned int p2, unsigned char trans);
00133
00139 bool getPieceInfo(unsigned int p, unsigned int * p_out, unsigned char * trans) const;
00140
00141 private:
00142
00143
00144 mirrorInfo_c(const mirrorInfo_c&);
00145 void operator=(const mirrorInfo_c&);
00146 };
00147
00154 class assembly_c {
00155
00156 private:
00157
00161 std::vector<placement_c> placements;
00162
00164 const symmetries_c * sym;
00165
00169 bool operator == (const assembly_c & b) const {
00170
00171
00172
00173
00174
00175 bt_assert(placements.size() == b.placements.size());
00176
00177 for (unsigned int i = 0; i < placements.size(); i++)
00178 if (!(placements[i] == b.placements[i]))
00179 return false;
00180
00181 return true;
00182 }
00183
00190 bool compare(const assembly_c & b, unsigned int pivot) const;
00191
00200 bool containsMirroredPieces(void) const;
00201
00206 bool validSolution(const problem_c * puz) const;
00207
00208 public:
00209
00210 assembly_c(const gridType_c * gt) : sym(gt->getSymmetries()) {}
00211
00215 assembly_c(const assembly_c * orig);
00216
00220 assembly_c(xmlParser_c & pars, unsigned int pieces, const gridType_c * gt);
00221
00223 void save(xmlWriter_c & xml) const;
00224
00228 void addPlacement(unsigned char tran, int x, int y, int z) {
00229 bt_assert(tran < sym->getNumTransformations());
00230 bt_assert(tran != UNPLACED_TRANS);
00231 placements.push_back(placement_c(tran, x, y, z));
00232 }
00233
00239 void addNonPlacement(void) {
00240 placements.push_back(placement_c(UNPLACED_TRANS, 0, 0, 0));
00241 }
00242
00244 unsigned int placementCount(void) const { return placements.size(); }
00245
00247 bool isPlaced(unsigned int num) const {
00248 return placements[num].getTransformation() != UNPLACED_TRANS;
00249 }
00250
00252 unsigned char getTransformation(unsigned int num) const {
00253 bt_assert(num < placements.size());
00254 bt_assert(placements[num].getTransformation() != UNPLACED_TRANS);
00255 return placements[num].getTransformation();
00256 }
00257
00259 int getX(unsigned int num) const {
00260 bt_assert(num < placements.size());
00261 bt_assert(placements[num].getTransformation() != UNPLACED_TRANS);
00262 return placements[num].getX();
00263 }
00264
00266 int getY(unsigned int num) const {
00267 bt_assert(num < placements.size());
00268 bt_assert(placements[num].getTransformation() != UNPLACED_TRANS);
00269 return placements[num].getY();
00270 }
00271
00273 int getZ(unsigned int num) const {
00274 bt_assert(num < placements.size());
00275 bt_assert(placements[num].getTransformation() != UNPLACED_TRANS);
00276 return placements[num].getZ();
00277 }
00278
00296 bool transform(unsigned char trans, const problem_c * puz, const mirrorInfo_c * mir);
00297
00302 bool smallerRotationExists(const problem_c * puz, unsigned int pivot, const mirrorInfo_c * mir, bool complete) const;
00303
00308 void exchangeShape(unsigned int s1, unsigned int s2);
00309
00316 int comparePieces(const assembly_c * b) const;
00317
00322 void sort(const problem_c * puz);
00323
00327 voxel_c * createSpace(const problem_c * puz) const;
00328
00329 void removePieces(unsigned int from, unsigned int cnt);
00330
00331 void addNonPlacedPieces(unsigned int from, unsigned int cnt);
00332
00333 private:
00334
00335
00336 assembly_c(const assembly_c&);
00337 void operator=(const assembly_c&);
00338
00339 };
00340
00341 #endif