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

FCSSoftDFSSolvingAlgorithm.h

Go to the documentation of this file.
00001 #ifndef MMANN_FCS_SOFT_DFS_SOLVING_ALGORITHM_H
00002 #define MMANN_FCS_SOFT_DFS_SOLVING_ALGORITHM_H
00003 
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include "FCSFreecellData.h" 
00007 #include "FCSFreecellAlgorithm.h"
00008 #include "FCSStateStorage.h"
00009 #include "FCHelpingAlgorithms.h"
00010 
00018 
00019 
00021 template <class SolvingAlgorithmType>
00022 class FCSSoftDFSSolvingAlgorithm : public SolvingAlgorithmType
00023 {
00024 public:
00026     FCSSoftDFSSolvingAlgorithm(FCCommandLineArguments* CommandLine);
00027 
00029     virtual ~FCSSoftDFSSolvingAlgorithm();
00030 
00036     virtual FCSStateSolvingReturnCodes Solve(FCSStateWithLocations* StateWithLocations, int Depth);
00037 
00042     virtual FCSStateSolvingReturnCodes Resume(int Depth);
00043 
00044 protected:
00046     FCSSoftDFSSolvingAlgorithm();
00047 
00049     void InitFCSSoftDFSSolvingAlgorithm();
00050 
00051 
00056     virtual FCSStateSolvingReturnCodes SolveOrResume(int Depth);
00057 
00059     virtual void IncreaseDFSMaxDepth();
00060 
00062     int m_DFSMaxDepth;
00063 
00065     FCSDerivedStatesList* m_SoftDFSDerivedStatesLists;
00066 
00068     int * m_SoftDFSCurrentStateIndexes;
00069 
00073     int * m_SoftDFSTestIndexes;
00074 
00077     int * m_SoftDFSNumberOfFreestacks;
00078 
00081     int * m_SoftDFSNumberOfFreecells;
00082 };
00083 
00084 template <class SolvingAlgorithmType>
00085 FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::FCSSoftDFSSolvingAlgorithm() : SolvingAlgorithmType()
00086 {
00087     InitFCSSoftDFSSolvingAlgorithm();
00088 }
00089 
00090 template <class SolvingAlgorithmType>
00091 void FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::InitFCSSoftDFSSolvingAlgorithm()
00092 {
00093     m_DFSMaxDepth = 0;
00094 
00095     //Initialize SoftDFS Stack
00096     m_SoftDFSDerivedStatesLists = NULL;
00097     m_SoftDFSCurrentStateIndexes = NULL;
00098     m_SoftDFSTestIndexes = NULL;
00099     m_SoftDFSNumberOfFreestacks = NULL;
00100     m_SoftDFSNumberOfFreecells = NULL;
00101 }
00102 
00103 
00104 template <class SolvingAlgorithmType>
00105 FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::FCSSoftDFSSolvingAlgorithm(FCCommandLineArguments* CommandLine) : SolvingAlgorithmType(CommandLine)
00106 {
00107     InitFCSSoftDFSSolvingAlgorithm();
00108 }
00109 
00110 template <class SolvingAlgorithmType>
00111 FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::~FCSSoftDFSSolvingAlgorithm()
00112 {
00113     // De-allocate the Soft-DFS specific stacks
00114     int Depth;
00115     for(Depth=0;Depth<m_NumberOfSolutionStates-1;Depth++)
00116         delete [] m_SoftDFSDerivedStatesLists[Depth].m_States;
00117 
00118     for(;Depth<m_DFSMaxDepth;Depth++)
00119         if (m_SoftDFSDerivedStatesLists[Depth].m_MaxNumberOfStates)
00120             delete [] m_SoftDFSDerivedStatesLists[Depth].m_States;
00121 
00122     delete [] m_SoftDFSDerivedStatesLists;
00123     m_SoftDFSDerivedStatesLists = NULL;
00124     delete [] m_SoftDFSTestIndexes;
00125     m_SoftDFSTestIndexes = NULL;
00126     delete [] m_SoftDFSCurrentStateIndexes;
00127     m_SoftDFSCurrentStateIndexes = NULL;
00128     delete [] m_SoftDFSNumberOfFreecells;
00129     m_SoftDFSNumberOfFreecells = NULL;
00130     delete [] m_SoftDFSNumberOfFreestacks;
00131     m_SoftDFSNumberOfFreestacks = NULL;
00132 }
00133 
00134 template <class SolvingAlgorithmType>
00135 FCSStateSolvingReturnCodes FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::Solve(FCSStateWithLocations* StateWithLocations, int Depth)
00136 {
00137     Depth = 0;
00138 
00139     //initializes part of the StateWithLocations
00140     InitSolve(StateWithLocations);
00141 
00142     IncreaseDFSMaxDepth();
00143     m_SolutionStates->Set(0, StateWithLocations);
00144 
00145     return SolveOrResume(Depth);
00146 }
00147 
00148 template <class SolvingAlgorithmType>
00149 FCSStateSolvingReturnCodes FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::Resume(int Depth)
00150 {
00151     Depth = m_NumberOfSolutionStates - 1;
00152 
00153     return SolveOrResume(Depth);
00154 }
00155 
00156 template <class SolvingAlgorithmType>
00157 FCSStateSolvingReturnCodes FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::SolveOrResume(int Depth)
00158 {
00159     FCSStateWithLocations *StateWithLocations,
00160                           *RecursiveStateWithLocations;
00161 
00162     FCSStateSolvingReturnCodes Check;
00163 
00164     int a;
00165 
00166     while (Depth >= 0)
00167     {
00168         
00169         //  Increase the "maximal" depth if it about to be exceeded.
00170         if (Depth+1 >= m_DFSMaxDepth)
00171             IncreaseDFSMaxDepth();
00172 
00173         // All the resultant states in the last test conducted were covered
00174         if (m_SoftDFSCurrentStateIndexes[Depth] == m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates)
00175         {
00176             if (m_SoftDFSTestIndexes[Depth] >= m_TestsOrderNumber)
00177             {
00178                 // Backtrack to the previous depth.
00179                 Depth--;
00180                 continue; // Just to make sure depth is not -1 now
00181             }
00182 
00183             m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates = 0;
00184             StateWithLocations = m_SolutionStates->Get(Depth, 0);
00185 
00186             // If this is the first test, then count the number of unoccupied
00187             // freeceels and stacks and check if we are done. */
00188             if (m_SoftDFSTestIndexes[Depth] == 0)
00189             {
00190                 int NumberOfFreeStacks = 0, 
00191                     NumberOfFreecells = 0;
00192 
00193                 m_DebugDisplayInfo->Display(m_StateType, m_NumberOfCheckedStates, Depth, StateWithLocations,
00194                     ((Depth == 0) ? 0 : m_SolutionStates->Get(Depth-1, 0)->m_VisitIterations), m_NumberOfStatesInCollection);
00195 
00196                 // Count the free-cells
00197                 for(a=0;a<m_NumberOfFreecells;a++)
00198                 {
00199                     if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00200                         NumberOfFreecells++;
00201                 }
00202 
00203                 // Count the number of unoccupied stacks
00204                 for(a=0;a<m_NumberOfStacks;a++)
00205                 {
00206                     if (StateWithLocations->GetStackLength(a) == 0)
00207                         NumberOfFreeStacks++;
00208                 }
00209 
00210                 // Check if we have reached the empty state
00211                 if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00212                 {
00213                     m_FinalState = StateWithLocations;
00214                     return FCS_STATE_WAS_SOLVED;
00215                 }
00216 
00217                 //  Cache num_freecells and num_freestacks in their 
00218                 //  appropriate stacks, so they won't be calculated over and over
00219                 //  again.
00220                 m_SoftDFSNumberOfFreecells[Depth] = NumberOfFreecells;
00221                 m_SoftDFSNumberOfFreestacks[Depth] = NumberOfFreeStacks;
00222             }
00223 
00224             if (m_SoftDFSTestIndexes[Depth] < m_TestsOrderNumber)
00225             {
00226                 Check = RunTest(m_TestsOrder[m_SoftDFSTestIndexes[Depth]] & FCS_TEST_ORDER_NO_FLAGS_MASK,
00227                                 StateWithLocations,
00228                                 Depth, 
00229                                 m_SoftDFSNumberOfFreestacks[Depth],
00230                                 m_SoftDFSNumberOfFreecells[Depth],
00231                                 &(m_SoftDFSDerivedStatesLists[Depth]));
00232 
00233                 if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00234                     (Check == FCS_STATE_EXCEEDS_MAX_NUM_TIMES) ||
00235                     (Check == FCS_STATE_SUSPEND_PROCESS))
00236                 {
00237                     // Have this test be re-performed
00238                     m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates = 0;
00239                     m_SoftDFSCurrentStateIndexes[Depth] = 0;
00240                     m_NumberOfSolutionStates = Depth+1;
00241 
00242                     return FCS_STATE_SUSPEND_PROCESS;
00243                 }
00244 
00245                 // Move the counter to the next test
00246                 m_SoftDFSTestIndexes[Depth]++;
00247             }
00248 
00249             // We just performed a test, so the index of the first state that
00250             // ought to be checked in this depth is 0.
00251             m_SoftDFSCurrentStateIndexes[Depth] = 0;
00252         }
00253 
00254         while (m_SoftDFSCurrentStateIndexes[Depth] < 
00255                m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates)
00256         {
00257             RecursiveStateWithLocations = m_SoftDFSDerivedStatesLists[Depth].m_States[
00258                 m_SoftDFSCurrentStateIndexes[Depth]];
00259 
00260             m_SoftDFSCurrentStateIndexes[Depth]++;
00261             if (!RecursiveStateWithLocations->m_Visited)
00262             {
00263                 m_NumberOfCheckedStates++;
00264 
00265                 RecursiveStateWithLocations->m_Visited = FCS_VISITED_VISITED;
00266                 RecursiveStateWithLocations->m_VisitIterations = m_NumberOfCheckedStates;
00267                 m_SolutionStates->Set(Depth+1, RecursiveStateWithLocations);
00268                 
00269                 //  I'm using current_state_indexes[depth]-1 because we already
00270                 //  increased it by one, so now it refers to the next state.
00271                 Depth++;
00272                 m_SoftDFSTestIndexes[Depth] = 0;
00273                 m_SoftDFSCurrentStateIndexes[Depth] = 0;
00274                 m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates = 0;
00275                 break;
00276             }
00277         }
00278     }
00279 
00280     m_NumberOfSolutionStates = 0;
00281 
00282     return FCS_STATE_IS_NOT_SOLVEABLE;
00283 }
00284 
00285 template <class SolvingAlgorithmType>
00286 void FCSSoftDFSSolvingAlgorithm<SolvingAlgorithmType>::IncreaseDFSMaxDepth()
00287 {
00288     //*** Check that the 16 could be a #define
00289     int NewDFSMaxDepth = m_DFSMaxDepth + 16;
00290 
00291     m_SolutionStates->ReallocArray(m_DFSMaxDepth, NewDFSMaxDepth);
00292     ReallocMoveStackArray(&m_ProtoSolutionMoves, m_DFSMaxDepth, NewDFSMaxDepth);
00293     Realloc<FCSDerivedStatesList>(&m_SoftDFSDerivedStatesLists, m_DFSMaxDepth, NewDFSMaxDepth);
00294     Realloc<int>(&m_SoftDFSCurrentStateIndexes, m_DFSMaxDepth, NewDFSMaxDepth);
00295     Realloc<int>(&m_SoftDFSTestIndexes, m_DFSMaxDepth, NewDFSMaxDepth);
00296     Realloc<int>(&m_SoftDFSNumberOfFreestacks, m_DFSMaxDepth, NewDFSMaxDepth);
00297     Realloc<int>(&m_SoftDFSNumberOfFreecells, m_DFSMaxDepth, NewDFSMaxDepth);
00298     
00299     for(int d=m_DFSMaxDepth; d<NewDFSMaxDepth; d++)
00300     {
00301         m_SolutionStates->Set(d, NULL);
00302         m_ProtoSolutionMoves[d] = NULL;
00303         m_SoftDFSDerivedStatesLists[d].m_MaxNumberOfStates = 0;
00304         m_SoftDFSTestIndexes[d] = 0;
00305         m_SoftDFSCurrentStateIndexes[d] = 0;
00306         m_SoftDFSDerivedStatesLists[d].m_NumberOfStates = 0;
00307         m_SoftDFSDerivedStatesLists[d].m_States = NULL;
00308     }
00309 
00310     m_DFSMaxDepth = NewDFSMaxDepth;
00311 }
00312 
00313 #endif

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