001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011: #ifndef UKPUZZLECORE_H
012: #define UKPUZZLECORE_H
013:
014: #include "afxtempl.h"
015: #include "UKPuzzleDef.h"
016: #include "UKIniAccess.h"
017:
018: #define UKPUZ_WRITEOUTPUT
019:
020:
021: #define UKPUZ_FTL
022:
023:
024:
025:
026:
027:
028:
029:
030:
031:
032:
033: struct SUKPuzzlePos
034: {
035: SUKPuzzlePos():x(0),y(0),z(0){}
036: SUKPuzzlePos(long nXPos,long nYPos,long nZPos):x(nXPos),y(nYPos),z(nZPos){}
037: SUKPuzzlePos(const SUKPuzzlePos &r):x(r.x),y(r.y),z(r.z){}
038:
039: SUKPuzzlePos operator+(const SUKPuzzlePos &r){SUKPuzzlePos tmp=*this;tmp+=r;return tmp;}
040: SUKPuzzlePos operator-(const SUKPuzzlePos &r){SUKPuzzlePos tmp=*this;tmp-=r;return tmp;}
041:
042: SUKPuzzlePos& operator+=(const SUKPuzzlePos &r){x+=r.x;y+=r.y;z+=r.z;return *this;}
043: SUKPuzzlePos& operator-=(const SUKPuzzlePos &r){x-=r.x;y-=r.y;z-=r.z;return *this;}
044:
045: BOOL operator==(const SUKPuzzlePos &r){return x==r.x && y==r.y && z==r.z;}
046:
047:
048: void RotateX(){long tmp=z;z=y;y=-tmp;}
049: void RotateY(){long tmp=z;z=x;x=-tmp;}
050: void RotateZ(){long tmp=y;y=x;x=-tmp;}
051:
052: long x;
053: long y;
054: long z;
055: };
056:
057: class CUKStone
058: {
059: private:
060: CUKStone(const CUKStone&);
061: CUKStone& operator= (const CUKStone&);
062: public:
063: CUKStone();
064: ~CUKStone();
065:
066: long GetMaxVariations(){return m_nMaxVariations;}
067:
068: BOOL SetStone(SUKPuzzlePos* pStone,long nCubeCount,long nDX,long nDY,long nDZ,long nPosition,long* pBlock);
069: BOOL CUKStone::SetStone(CUKStone& rStone,long nDX,long nDY,long nDZ,long nPosition,long* pBlock);
070:
071: long GetCubeCount(){return m_nCubeCount;}
072:
073: long GetPos(long nCubeNo,long nVariation){return m_pCubes[nVariation][nCubeNo];}
074: long* GetStone(long nVariation){return m_pCubes[nVariation];}
075: protected:
076: enum {enInvalid=MAXLONG};
077: virtual BOOL IsInvalid(long nPosition,long* pBlock);
078:
079: virtual long GetCubeSortPosition(SUKPuzzlePos &rStone);
080:
081: void EliminateInvalidStones();
082: void EliminateDuplicatedStones();
083: private:
084: long m_nMaxVariations;
085:
086: long m_nCubeCount;
087: long** m_pCubes;
088: };
089:
090: struct SUKStoneDesc
091: {
092: long nVariation;
093: long nActiveStone;
094: long nPosIndex;
095: long nPosition;
096: long nStoneID;
097: long nQuickIndex;
098: CUKStone* pStones;
099: };
100:
101: class CUKPuzzleCore
102: {
103: public:
104: CUKPuzzleCore(long nFirstStoneOnPos_0=-1,long nLastStoneOnPos_0=-1,LPCTSTR szIniFileName="",LPCTSTR szOutputFileName="");
105: ~CUKPuzzleCore();
106:
107: BOOL Init(){return Init(m_nFirstStoneOnPos_0,m_nLastStoneOnPos_0,m_strIniFileName,m_strOutputFileName);}
108: BOOL Init(LPCTSTR szIniFileName,LPCTSTR szOutputFileName){return Init(m_nFirstStoneOnPos_0,m_nLastStoneOnPos_0,szIniFileName,szOutputFileName);}
109: BOOL Init(long nFirstStoneOnPos_0,long nLastStoneOnPos_0,LPCTSTR szIniFileName,LPCTSTR szOutputFileName);
110: void Deinit();
111:
112: UKPUZ_STATE DoNextStep();
113:
114: DWORD GetSolutions(){return m_nSolutionsFound;}
115: BOOL HasFinished(){return m_bHasFinished;}
116:
117: protected:
118:
119: BOOL ReadCoordinate(CUKIniAccess& theFile,LPCTSTR szSection,LPCTSTR szKey,SUKPuzzlePos &rPos);
120: BOOL ReadStone(CUKIniAccess& theFile,LPCTSTR szSection,LPCTSTR szKey,CUKStone &rStone,long &nStoneCount,long nDX,long nDY,long nDZ,long nPosition,long* pBlock);
121:
122:
123:
124: void WriteOutput(LPCTSTR szFileName);
125: void SolutionFound();
126:
127: BOOL PreCheck1();
128: BOOL PreCheck2();
129:
130: BOOL InsertStone();
131:
132: void RemoveStone();
133:
134: long GetNextFreeStone(long nQuickIndex,long nBeginAfter=-1,long nPosition=0);
135: long GetNextFreePosIndex();
136:
137: void SetStoneIsUsedFALSE(long nStone);
138: void SetStoneIsUsedTRUE(long nStone);
139:
140:
141:
142:
143: void TryInsertNextStone();
144: void TryReplaceStone();
145:
146:
147: protected:
148: virtual BOOL PreInitBlock();
149: virtual BOOL InitPositionOrder();
150: virtual BOOL PostInitBlock();
151: virtual BOOL InitStones();
152:
153: virtual void DeinitStones();
154: virtual void DeinitPositionOrder();
155: virtual void DeinitBlock();
156:
157: public:
158: enum
159: {
160: enNextStone=1,
161: enReplaceStone=2,
162: enFinished=3
163: };
164: enum
165: {
166: enMaxCubesPerStone=32,
167: };
168:
169: protected:
170:
171: long m_nPreCheckLevel;
172: long m_nFirstPreCheckStone;
173: long m_nLastPreCheckStone;
174:
175: CString m_strIniFileName;
176: BOOL m_bLoadFromIni;
177:
178: long m_nXSize;
179: long m_nYSize;
180: long m_nZSize;
181: long m_nEdgeZone;
182: long m_nDX;
183: long m_nDY;
184: long m_nDZ;
185: long m_nPositionCount;
186: long m_nStoneCount;
187: long m_nEntireStoneCount;
188:
189: long m_nSymetriePosCount;
190: BOOL m_bEnhancedSymertyCheck;
191:
192: CString m_strOutputFileName;
193: long m_nWriteEveryNSolution;
194: BOOL m_bShowLegend;
195:
196: protected:
197:
198: DWORD m_nSolutionsFound;
199: BOOL m_bHasFinished;
200:
201:
202: BOOL m_bIsInit;
203:
204: long* m_pBlock;
205: long* m_pPositions;
206:
207: enum {enPreDefStones=64};
208: CUKStone** m_ppStones[enPreDefStones];
209: long* m_pAvailableStones;
210:
211:
212: long m_nNextStep;
213: long m_nUsedStoneCount;
214: SUKStoneDesc* m_pUsedStones;
215: SUKStoneDesc m_ActiveStoneDesc;
216:
217:
218: long m_nNextFreeStone;
219: long m_nFirstActiveStone;
220: long m_nNextFreePosIndex;
221:
222: long m_SymetriePos[8];
223: SUKPuzzlePos m_SymetriePuzzlePos[8];
224:
225: long m_nSymetryStones;
226: long m_nSymetryStonesNeeded;
227:
228: long m_nFirstStoneOnPos_0;
229: long m_nLastStoneOnPos_0;
230:
231:
232: public:
233:
234: LONGLONG m_nTrys;
235: };
236:
237: #endif