Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

FCSBFSSolvingAlgorithm.h

Go to the documentation of this file.
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     // Initialize the BFS queue. We have one dummy element at the beginning
00081     // in order to make operations simpler.
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     // Free the BFS linked list
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     //initializes part of the StateWithLocations
00114     InitSolve(StateWithLocations);
00115 
00116     // Initialize the first element to indicate it is the first
00117     StateWithLocations->m_Parent = NULL;
00118     StateWithLocations->m_MovesToParent = NULL;
00119     StateWithLocations->m_Depth = 0;
00120 
00121     // Continue as long as there are states in the queue or priority queue.
00122     while (StateWithLocations != NULL)
00123     {
00124         if (StateWithLocations->m_Visited & FCS_VISITED_VISITED)
00125             goto NextState;
00126 
00127         // Count the free-cells
00128         NumberOfFreecells = 0;
00129         for(a=0;a<m_NumberOfFreecells;a++)
00130         {
00131             if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00132                 NumberOfFreecells++;
00133         }
00134 
00135         // Count the number of unoccupied stacks
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             // Free the memory that was allocated by derived.
00151             DeleteDerived(&Derived);
00152             return FCS_STATE_WAS_SOLVED;
00153         }
00154 
00155         // Increase the number of iterations by one . This
00156         // is meant to make sure we do not entered this state before which
00157         // will lead to a false iterations count.
00158         m_NumberOfCheckedStates++;
00159 
00160         // Do all the tests at one go, because that the way it should be
00161         //  done for BFS and A*
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                 // Save the current position in the scan
00175                 m_FirstStateToCheck = StateWithLocations;
00176 
00177                 DeleteDerived(&Derived);
00178                 return FCS_STATE_SUSPEND_PROCESS;
00179             }
00180         }
00181 
00182         //  Insert all the derived states into the PQ or Queue
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         //  Extract the next item in the queue/priority queue.
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     // Free the memory that was allocated by derived.
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     // Continue as long as there are states in the queue or priority queue.
00225     while (StateWithLocations != NULL)
00226     {
00227         if (StateWithLocations->m_Visited & FCS_VISITED_VISITED)
00228             goto NextState;
00229 
00230         // Count the free-cells
00231         for(a=0;a<m_NumberOfFreecells;a++)
00232         {
00233             if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00234                 NumberOfFreecells++;
00235         }
00236 
00237         // Count the number of unoccupied stacks
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             // Free the memory that was allocated by derived.
00249             DeleteDerived(&Derived);
00250             return FCS_STATE_WAS_SOLVED;
00251         }
00252 
00253         // Do all the tests at one go, because that the way it should be
00254         //  done for BFS and A*
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                 // Save the current position in the scan
00268                 m_FirstStateToCheck = StateWithLocations;
00269 
00270                 DeleteDerived(&Derived);
00271                 return FCS_STATE_SUSPEND_PROCESS;
00272             }
00273         }
00274 
00275         //  Insert all the derived states into the PQ or Queue
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     // Free the memory that was allocated by derived.
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

Generated on Sat Nov 5 11:20:15 2005 for Cpp Freecell Solver by  doxygen 1.4.4