00001 #ifndef MMANN_FCS_BFS_SOLVING_ALGORITHM_H
00002 #define MMANN_FCS_BFS_SOLVING_ALGORITHM_H
00003
00011
00012 #include <stdlib.h>
00013 #include "FCSFreecellData.h"
00014 #include "FCSFreecellAlgorithm.h"
00015
00017 template <class SolvingAlgorithmType>
00018 class FCSBFSSolvingAlgorithm : public SolvingAlgorithmType
00019 {
00020 public:
00022 FCSBFSSolvingAlgorithm(FCCommandLineArguments* CommandLine);
00023
00025 virtual ~FCSBFSSolvingAlgorithm();
00026
00032 virtual FCSStateSolvingReturnCodes Solve(FCSStateWithLocations* StateWithLocations, int Depth);
00033
00038 virtual FCSStateSolvingReturnCodes Resume(int Depth);
00039
00040 protected:
00042 FCSBFSSolvingAlgorithm();
00044 void InitFCSBFSSolvingAlgorithm();
00045
00049 void BFSEnqueueState(FCSStateWithLocations* StateWithLocations);
00050
00052 FCSStateWithLocationsLinkedList* m_BFSQueue;
00053
00055 FCSStateWithLocationsLinkedList* m_BFSQueueLastItem;
00056
00058 FCSStateWithLocations* m_FirstStateToCheck;
00059 };
00060
00061 template <class SolvingAlgorithmType>
00062 FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::FCSBFSSolvingAlgorithm() : SolvingAlgorithmType()
00063 {
00064 InitFCSBFSSolvingAlgorithm();
00065 }
00066
00067 template <class SolvingAlgorithmType>
00068 void FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::InitFCSBFSSolvingAlgorithm()
00069 {
00070 m_BFSQueue = NULL;
00071 m_BFSQueueLastItem = NULL;
00072 m_FirstStateToCheck = NULL;
00073 }
00074
00075 template <class SolvingAlgorithmType>
00076 FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::FCSBFSSolvingAlgorithm(FCCommandLineArguments* CommandLine) : SolvingAlgorithmType(CommandLine)
00077 {
00078 InitFCSBFSSolvingAlgorithm();
00079
00080
00081
00082 m_BFSQueue = new FCSStateWithLocationsLinkedList();
00083 m_BFSQueue->m_Next = new FCSStateWithLocationsLinkedList();
00084 m_BFSQueueLastItem = m_BFSQueue->m_Next;
00085 m_BFSQueueLastItem->m_Next = NULL;
00086 }
00087
00088 template <class SolvingAlgorithmType>
00089 FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::~FCSBFSSolvingAlgorithm()
00090 {
00091
00092 FCSStateWithLocationsLinkedList *Item = m_BFSQueue,
00093 *NextItem;
00094 while (Item != NULL)
00095 {
00096 NextItem = Item->m_Next;
00097 delete Item;
00098 Item = NextItem;
00099 }
00100 }
00101
00102 template <class SolvingAlgorithmType>
00103 FCSStateSolvingReturnCodes FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::Solve(FCSStateWithLocations* StateWithLocations, int Depth)
00104 {
00105 int NumberOfFreeStacks = 0,
00106 NumberOfFreecells = 0,
00107 DerivedIndex, a;
00108
00109 FCSStateSolvingReturnCodes Check;
00110
00111 FCSDerivedStatesList Derived;
00112
00113
00114 InitSolve(StateWithLocations);
00115
00116
00117 StateWithLocations->m_Parent = NULL;
00118 StateWithLocations->m_MovesToParent = NULL;
00119 StateWithLocations->m_Depth = 0;
00120
00121
00122 while (StateWithLocations != NULL)
00123 {
00124 if (StateWithLocations->m_Visited & FCS_VISITED_VISITED)
00125 goto NextState;
00126
00127
00128 NumberOfFreecells = 0;
00129 for(a=0;a<m_NumberOfFreecells;a++)
00130 {
00131 if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00132 NumberOfFreecells++;
00133 }
00134
00135
00136 NumberOfFreeStacks = 0;
00137 for(a=0;a<m_NumberOfStacks;a++)
00138 {
00139 if (StateWithLocations->GetStackLength(a) == 0)
00140 NumberOfFreeStacks++;
00141 }
00142
00143 m_DebugDisplayInfo->Display(m_StateType, m_NumberOfCheckedStates, StateWithLocations->m_Depth, StateWithLocations,
00144 ((StateWithLocations->m_Parent == NULL) ? 0 : StateWithLocations->m_Parent->m_VisitIterations), m_NumberOfStatesInCollection);
00145
00146 if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00147 {
00148 m_FinalState = StateWithLocations;
00149
00150
00151 DeleteDerived(&Derived);
00152 return FCS_STATE_WAS_SOLVED;
00153 }
00154
00155
00156
00157
00158 m_NumberOfCheckedStates++;
00159
00160
00161
00162
00163 Derived.m_NumberOfStates = 0;
00164 for(a=0 ; a < m_TestsOrderNumber; a++)
00165 {
00166 Check = RunTest(m_TestsOrder[a] & FCS_TEST_ORDER_NO_FLAGS_MASK, StateWithLocations,
00167 StateWithLocations->m_Depth, NumberOfFreeStacks,
00168 NumberOfFreecells, &Derived);
00169
00170 if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00171 (Check == FCS_STATE_EXCEEDS_MAX_NUM_TIMES) ||
00172 (Check == FCS_STATE_SUSPEND_PROCESS))
00173 {
00174
00175 m_FirstStateToCheck = StateWithLocations;
00176
00177 DeleteDerived(&Derived);
00178 return FCS_STATE_SUSPEND_PROCESS;
00179 }
00180 }
00181
00182
00183 for(DerivedIndex = 0; DerivedIndex < Derived.m_NumberOfStates; DerivedIndex++)
00184 BFSEnqueueState(Derived.m_States[DerivedIndex]);
00185
00186 StateWithLocations->m_Visited |= FCS_VISITED_VISITED;
00187 StateWithLocations->m_VisitIterations = m_NumberOfCheckedStates-1;
00188
00189 NextState:
00190
00191
00192 if (m_BFSQueue->m_Next != m_BFSQueueLastItem)
00193 {
00194 FCSStateWithLocationsLinkedList* SaveItem = m_BFSQueue->m_Next;
00195 StateWithLocations = SaveItem->m_State;
00196 m_BFSQueue->m_Next = m_BFSQueue->m_Next->m_Next;
00197 delete SaveItem;
00198 }
00199 else
00200 {
00201 StateWithLocations = NULL;
00202 }
00203 }
00204
00205
00206 DeleteDerived(&Derived);
00207
00208 return FCS_STATE_IS_NOT_SOLVEABLE;
00209 }
00210
00211 template <class SolvingAlgorithmType>
00212 FCSStateSolvingReturnCodes FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::Resume(int Depth)
00213 {
00214 FCSStateWithLocations* StateWithLocations = m_FirstStateToCheck;
00215
00216 int NumberOfFreeStacks = 0,
00217 NumberOfFreecells = 0,
00218 DerivedIndex, a;
00219
00220 FCSStateSolvingReturnCodes Check;
00221
00222 FCSDerivedStatesList Derived;
00223
00224
00225 while (StateWithLocations != NULL)
00226 {
00227 if (StateWithLocations->m_Visited & FCS_VISITED_VISITED)
00228 goto NextState;
00229
00230
00231 for(a=0;a<m_NumberOfFreecells;a++)
00232 {
00233 if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00234 NumberOfFreecells++;
00235 }
00236
00237
00238 for(a=0;a<m_NumberOfStacks;a++)
00239 {
00240 if (StateWithLocations->GetStackLength(a) == 0)
00241 NumberOfFreeStacks++;
00242 }
00243
00244 if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00245 {
00246 m_FinalState = StateWithLocations;
00247
00248
00249 DeleteDerived(&Derived);
00250 return FCS_STATE_WAS_SOLVED;
00251 }
00252
00253
00254
00255
00256 Derived.m_NumberOfStates = 0;
00257 for(a=0 ; a < m_TestsOrderNumber; a++)
00258 {
00259 Check = RunTest(m_TestsOrder[a] & FCS_TEST_ORDER_NO_FLAGS_MASK, StateWithLocations,
00260 StateWithLocations->m_Depth, NumberOfFreeStacks,
00261 NumberOfFreecells, &Derived);
00262
00263 if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00264 (Check == FCS_STATE_EXCEEDS_MAX_NUM_TIMES) ||
00265 (Check == FCS_STATE_SUSPEND_PROCESS))
00266 {
00267
00268 m_FirstStateToCheck = StateWithLocations;
00269
00270 DeleteDerived(&Derived);
00271 return FCS_STATE_SUSPEND_PROCESS;
00272 }
00273 }
00274
00275
00276 for(DerivedIndex = 0; DerivedIndex < Derived.m_NumberOfStates; DerivedIndex++)
00277 BFSEnqueueState(Derived.m_States[DerivedIndex]);
00278
00279 StateWithLocations->m_Visited |= FCS_VISITED_VISITED;
00280 StateWithLocations->m_VisitIterations = m_NumberOfCheckedStates-1;
00281
00282 NextState:
00283
00284 if (m_BFSQueue->m_Next != m_BFSQueueLastItem)
00285 {
00286 FCSStateWithLocationsLinkedList* SaveItem = m_BFSQueue->m_Next;
00287 StateWithLocations = SaveItem->m_State;
00288 m_BFSQueue->m_Next = m_BFSQueue->m_Next->m_Next;
00289 delete SaveItem;
00290 }
00291 else
00292 {
00293 StateWithLocations = NULL;
00294 }
00295 }
00296
00297
00298 DeleteDerived(&Derived);
00299
00300 return FCS_STATE_IS_NOT_SOLVEABLE;
00301 }
00302
00303 template <class SolvingAlgorithmType>
00304 void FCSBFSSolvingAlgorithm<SolvingAlgorithmType>::BFSEnqueueState(FCSStateWithLocations* StateWithLocations)
00305 {
00306
00307 m_BFSQueueLastItem->m_Next = new FCSStateWithLocationsLinkedList();
00308 m_BFSQueueLastItem->m_State = StateWithLocations;
00309 m_BFSQueueLastItem->m_Next->m_Next = NULL;
00310 m_BFSQueueLastItem = m_BFSQueueLastItem->m_Next;
00311 }
00312
00313 #endif