00001 #ifndef MMANN_FCS_OPTIMIZE_SOLVING_ALGORITHM_H
00002 #define MMANN_FCS_OPTIMIZE_SOLVING_ALGORITHM_H
00003
00011
00012 #include "FCSBFSSolvingAlgorithm.h"
00013
00017 template <class SolvingAlgorithmType>
00018 class FCSOptimizeSolvingAlgorithm : public FCSBFSSolvingAlgorithm<SolvingAlgorithmType>
00019 {
00020 public:
00022 FCSOptimizeSolvingAlgorithm(SolvingAlgorithmType* SolvingAlgorithm);
00023
00028 virtual ~FCSOptimizeSolvingAlgorithm();
00029
00035 virtual FCSStateSolvingReturnCodes Solve(FCSStateWithLocations* StateWithLocations, int Depth);
00036
00043 virtual FCSStateSolvingReturnCodes Resume(int Depth);
00044
00045 protected:
00056 virtual inline bool CheckStateEnd(FCSStateWithLocations** NewStateWithLocations, FCSStateWithLocations* StateWithLocations,
00057 FCSDerivedStatesList** DerivedStateList, FCSMoveStack** Move, FCSMove** TempMove, int depth,
00058 FCSStateSolvingReturnCodes* ReturnCode);
00059
00061 int m_SavedNumberOfStatePacks;
00062
00064 AFCSStateWithLocationsMatrix** m_SavedStatePacks;
00065 };
00066
00067 template <class SolvingAlgorithmType>
00068 FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::FCSOptimizeSolvingAlgorithm(SolvingAlgorithmType* SolvingAlgorithm) : FCSBFSSolvingAlgorithm<SolvingAlgorithmType>()
00069 {
00070 IsOptimizeClass = true;
00071
00072
00073
00074 m_BFSQueue = new FCSStateWithLocationsLinkedList();
00075 m_BFSQueue->m_Next = new FCSStateWithLocationsLinkedList();
00076 m_BFSQueueLastItem = m_BFSQueue->m_Next;
00077 m_BFSQueueLastItem->m_Next = NULL;
00078
00079
00080 m_StateType = SolvingAlgorithm->m_StateType;
00081 m_StatePacks = SolvingAlgorithm->m_StatePacks;
00082 m_SavedStatePacks = &SolvingAlgorithm->m_StatePacks;
00083 m_MaxNumberOfStatePacks = SolvingAlgorithm->m_MaxNumberOfStatePacks;
00084 m_SavedNumberOfStatePacks = m_NumberOfStatePacks = SolvingAlgorithm->m_NumberOfStatePacks;
00085 m_NumberOfStatesInLastPack = SolvingAlgorithm->m_NumberOfStatesInLastPack;
00086 m_StatePackLength = SolvingAlgorithm->m_StatePackLength;
00087
00088 m_FinalState = SolvingAlgorithm->m_FinalState;
00089
00090 m_NumberOfCheckedStates = SolvingAlgorithm->m_NumberOfCheckedStates;
00091 m_MaxDepth = SolvingAlgorithm->m_MaxDepth;
00092 m_MaxNumberOfCheckedStates = SolvingAlgorithm->m_MaxNumberOfCheckedStates;
00093
00094 m_DebugDisplayInfo = SolvingAlgorithm->m_DebugDisplayInfo;
00095 m_TestsOrderNumber = SolvingAlgorithm->m_TestsOrderNumber;
00096 memcpy(m_TestsOrder, SolvingAlgorithm->m_TestsOrder, sizeof(int)*FCS_TESTS_NUM);
00097
00098 m_StateStorage = SolvingAlgorithm->m_StateStorage;
00099 m_StackStorage = SolvingAlgorithm->m_StackStorage;
00100
00101 m_NumberOfFreecells = SolvingAlgorithm->m_NumberOfFreecells;
00102 m_NumberOfStacks = SolvingAlgorithm->m_NumberOfStacks;
00103 m_NumberOfDecks = SolvingAlgorithm->m_NumberOfDecks;
00104
00105 m_SequencesAreBuiltBy = SolvingAlgorithm->m_SequencesAreBuiltBy;
00106 m_IsUnlimitedSequenceMove = SolvingAlgorithm->m_IsUnlimitedSequenceMove;
00107 m_EmptyStacksFill = SolvingAlgorithm->m_EmptyStacksFill;
00108 m_OptimizeSolutionPath = SolvingAlgorithm->m_OptimizeSolutionPath;
00109
00110 m_CompareFunction = SolvingAlgorithm->m_CompareFunction;
00111 m_MD5Hash = SolvingAlgorithm->m_MD5Hash;
00112
00113 m_IndirectCompare = SolvingAlgorithm->m_IndirectCompare;
00114 m_IndirectHash = SolvingAlgorithm->m_IndirectHash;
00115 }
00116
00117 template <class SolvingAlgorithmType>
00118 FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::~FCSOptimizeSolvingAlgorithm()
00119 {
00120 for(int p=m_SavedNumberOfStatePacks; p<m_NumberOfStatePacks;p++)
00121 m_StatePacks->DeleteArray(p);
00122
00123 (*m_SavedStatePacks) = m_StatePacks;
00124 }
00125
00126 template <class SolvingAlgorithmType>
00127 bool FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::CheckStateEnd(FCSStateWithLocations** NewStateWithLocations, FCSStateWithLocations* StateWithLocations,
00128 FCSDerivedStatesList** DerivedStateList, FCSMoveStack** Move, FCSMove** TempMove, int depth,
00129 FCSStateSolvingReturnCodes* ReturnCode)
00130 {
00131 FCSStateWithLocations* ExistingState;
00132 FCSStateSolvingReturnCodes Check;
00133
00134
00135
00136
00137
00138 (*TempMove)->SetType(FCS_MOVE_TYPE_CANONIZE);
00139 (*Move)->Push(*TempMove);
00140
00141 Check = CheckAndAddState(*NewStateWithLocations, &ExistingState, depth);
00142
00143 if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00144 (Check == FCS_STATE_SUSPEND_PROCESS))
00145 {
00146
00147
00148 (*NewStateWithLocations)->CleanState();
00149 *ReturnCode = Check;
00150 return true;
00151 }
00152 else if (Check == FCS_STATE_ALREADY_EXISTS)
00153 {
00154 StatePackRelease();
00155
00156
00157
00158
00159
00160 if (ExistingState->m_Depth > StateWithLocations->m_Depth+1)
00161 {
00162
00163 FCSMoveStack* MovesCopy = (*Move)->Copy();
00164
00165
00166
00167 delete [] ExistingState->m_MovesToParent;
00168 ExistingState->m_MovesToParent = MovesCopy;
00169 ExistingState->m_Parent = StateWithLocations;
00170 ExistingState->m_Depth = StateWithLocations->m_Depth + 1;
00171 }
00172
00173 (*DerivedStateList)->AddState(ExistingState);
00174 }
00175 else
00176 {
00177
00178
00179
00180
00181 (*DerivedStateList)->AddState(*NewStateWithLocations);
00182
00183
00184
00185 (*Move) = CreateMoveStack();
00186 }
00187
00188 return false;
00189 }
00190
00191 template <class SolvingAlgorithmType>
00192 FCSStateSolvingReturnCodes FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::Resume(int Depth)
00193 {
00194 return FCS_STATE_IS_NOT_SOLVEABLE;
00195 }
00196
00197 template <class SolvingAlgorithmType>
00198 FCSStateSolvingReturnCodes FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::Solve(FCSStateWithLocations* StateWithLocations, int Depth)
00199 {
00200
00201 int NumberOfFreeStacks = 0,
00202 NumberOfFreecells = 0,
00203 DerivedIndex, a;
00204
00205 FCSStateSolvingReturnCodes Check;
00206
00207 FCSDerivedStatesList Derived;
00208
00209
00210 StateWithLocations->m_Parent = NULL;
00211 StateWithLocations->m_MovesToParent = NULL;
00212 StateWithLocations->m_Depth = 0;
00213
00214
00215 while (StateWithLocations != NULL)
00216 {
00217 if (!(StateWithLocations->m_Visited & FCS_VISITED_IN_SOLUTION_PATH))
00218 {
00219 goto NextState;
00220 }
00221
00222 if (StateWithLocations->m_Visited & FCS_VISITED_IN_OPTIMIZED_PATH)
00223 {
00224 goto NextState;
00225 }
00226
00227
00228 NumberOfFreecells = 0;
00229 for(a=0;a<m_NumberOfFreecells;a++)
00230 {
00231 if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00232 NumberOfFreecells++;
00233 }
00234
00235
00236 NumberOfFreeStacks = 0;
00237 for(a=0;a<m_NumberOfStacks;a++)
00238 {
00239 if (StateWithLocations->GetStackLength(a) == 0)
00240 NumberOfFreeStacks++;
00241 }
00242
00243 m_DebugDisplayInfo->Display(m_StateType, m_NumberOfCheckedStates, StateWithLocations->m_Depth, StateWithLocations,
00244 ((StateWithLocations->m_Parent == NULL) ? 0 : StateWithLocations->m_Parent->m_VisitIterations), m_NumberOfStatesInCollection);
00245
00246 if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00247 {
00248 m_FinalState = StateWithLocations;
00249
00250
00251 DeleteDerived(&Derived);
00252 return FCS_STATE_WAS_SOLVED;
00253 }
00254
00255
00256
00257
00258 m_NumberOfCheckedStates++;
00259
00260
00261
00262
00263 Derived.m_NumberOfStates = 0;
00264 for(a=0 ; a < m_TestsOrderNumber; a++)
00265 {
00266 Check = RunTest(m_TestsOrder[a] & FCS_TEST_ORDER_NO_FLAGS_MASK, StateWithLocations,
00267 StateWithLocations->m_Depth, NumberOfFreeStacks,
00268 NumberOfFreecells, &Derived);
00269
00270 if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00271 (Check == FCS_STATE_EXCEEDS_MAX_NUM_TIMES) ||
00272 (Check == FCS_STATE_SUSPEND_PROCESS))
00273 {
00274
00275 m_FirstStateToCheck = StateWithLocations;
00276
00277 DeleteDerived(&Derived);
00278 return FCS_STATE_SUSPEND_PROCESS;
00279 }
00280 }
00281
00282
00283 for(DerivedIndex = 0; DerivedIndex < Derived.m_NumberOfStates; DerivedIndex++)
00284 BFSEnqueueState(Derived.m_States[DerivedIndex]);
00285
00286 StateWithLocations->m_Visited |= FCS_VISITED_IN_OPTIMIZED_PATH;
00287 StateWithLocations->m_VisitIterations = m_NumberOfCheckedStates-1;
00288
00289 NextState:
00290
00291
00292 if (m_BFSQueue->m_Next != m_BFSQueueLastItem)
00293 {
00294 FCSStateWithLocationsLinkedList* SaveItem = m_BFSQueue->m_Next;
00295 StateWithLocations = SaveItem->m_State;
00296 m_BFSQueue->m_Next = m_BFSQueue->m_Next->m_Next;
00297 delete SaveItem;
00298 }
00299 else
00300 {
00301 StateWithLocations = NULL;
00302 }
00303 }
00304
00305
00306 DeleteDerived(&Derived);
00307
00308 return FCS_STATE_IS_NOT_SOLVEABLE;
00309 }
00310 #endif