001: /////////////////////////////////////////////////////////////////////////////

002: //Projectname         : 

003: //Filename                : UKPuzzleCore.h 

004: //Classname                : CUKPuzzleCore

005: //Author                : Ulrich Kraemer [uk]

006: //Date                        : 25.03.2003

007: //Changes                : 

008: //////////////////////////////////////////////////////////////////////////////

009: //Synchronization and error handling is not implemenmted yet

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: //FASTER THAN LIGHT

021: #define UKPUZ_FTL
022: 
023: //The FTL mode deactivates also the UKPUZ_WRITEOUTPUT function

024: //#if defined (UKPUZ_FTL) && defined(UKPUZ_WRITEOUTPUT)

025: //#undef UKPUZ_WRITEOUTPUT

026: //#endif

027: 
028: 
029: //////////////////////////////////////////////////////////////////////////////

030: //puzzle core class

031: // in this class are all calculations done

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:         //very specialized methodes (the angle of rotation has no effect)

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); //can be overwritten (depends on position order)

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;//Reference to Correct Cube

088: };
089: 
090: struct SUKStoneDesc        //Stonedescriptor

091: {
092:         long nVariation;
093:         long nActiveStone;
094:         long nPosIndex;
095:         long nPosition;
096:         long nStoneID;//temporary unique id (m_nUsedStoneCount)

097:         long nQuickIndex;
098:         CUKStone* pStones;                //StoneList

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:                 //Tool Functions

124:                 void WriteOutput(LPCTSTR szFileName);
125:                 void SolutionFound();
126: 
127:                 BOOL PreCheck1();
128:                 BOOL PreCheck2();
129: 
130:                 BOOL InsertStone();//Check The Stone Described by the Head of UsedStones List

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:                 //Basic Steps

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,//there are no more allowed at the moment

167:                 };
168: 
169:         protected:
170:                 //dynamic loaded parameters

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;                        //Number of Different Stones (ini-File Stone Count)

187:                 long m_nEntireStoneCount;        //Number of Stones

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:                 //statistics and status

198:                 DWORD        m_nSolutionsFound;        //all Solutions in the 3*4*5 Block

199:                 BOOL        m_bHasFinished;
200: 
201:                 //environment

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:                 //dynamic attributes (floating control) 

212:                 long                        m_nNextStep;
213:                 long                        m_nUsedStoneCount;
214:                 SUKStoneDesc*        m_pUsedStones;//[enStoneCount];

215:                 SUKStoneDesc        m_ActiveStoneDesc;
216: 
217:                 //optimizing vars

218:                 long        m_nNextFreeStone;
219:                 long        m_nFirstActiveStone;
220:                 long        m_nNextFreePosIndex;
221: 
222:                 long                        m_SymetriePos[8];//maximum 8 corners

223:                 SUKPuzzlePos        m_SymetriePuzzlePos[8];//SymetriePos 0 must be first pos

224: 
225:                 long        m_nSymetryStones;
226:                 long        m_nSymetryStonesNeeded;
227: 
228:                 long        m_nFirstStoneOnPos_0;
229:                 long        m_nLastStoneOnPos_0;
230: 
231:                 //long*                        m_pBlockPosToPosIndex;

232:         public:
233:                 //test vars

234:                 LONGLONG m_nTrys;
235: };
236: 
237: #endif