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

FCSDFSSolvingAlgorithm.h

Go to the documentation of this file.
00001 #ifndef MMANN_FCS_DFS_SOLVING_ALGORITHM_H
00002 #define MMANN_FCS_DFS_SOLVING_ALGORITHM_H
00003 
00011 
00012 #include <stdlib.h>
00013 #include "FCSFreecellData.h"
00014 #include "FCSFreecellAlgorithm.h"
00015 
00017 template <class SolvingAlgorithmType>
00018 class FCSDFSSolvingAlgorithm : public SolvingAlgorithmType
00019 {
00020 public:
00022     FCSDFSSolvingAlgorithm(FCCommandLineArguments* CommandLine);
00023 
00025     virtual ~FCSDFSSolvingAlgorithm();
00026 
00032     virtual FCSStateSolvingReturnCodes Solve(FCSStateWithLocations* StateWithLocations, int Depth);
00033 
00038     virtual FCSStateSolvingReturnCodes Resume(int Depth);
00039 
00040 protected:
00042     FCSDFSSolvingAlgorithm();
00043     
00045     void InitFCSDFSSolvingAlgorithm();
00046 
00048     bool m_IsInitialized;
00049 };
00050 
00051 template <class SolvingAlgorithmType>
00052 FCSDFSSolvingAlgorithm<SolvingAlgorithmType>::FCSDFSSolvingAlgorithm() : SolvingAlgorithmType()
00053 {
00054     InitFCSDFSSolvingAlgorithm();
00055 }
00056 
00057 template <class SolvingAlgorithmType>
00058 void FCSDFSSolvingAlgorithm<SolvingAlgorithmType>::InitFCSDFSSolvingAlgorithm()
00059 {
00060     m_IsInitialized = false;
00061 }
00062 
00063 template <class SolvingAlgorithmType>
00064 FCSDFSSolvingAlgorithm<SolvingAlgorithmType>::FCSDFSSolvingAlgorithm(FCCommandLineArguments* CommandLine) : SolvingAlgorithmType(CommandLine)
00065 {
00066     InitFCSDFSSolvingAlgorithm();
00067 }
00068 
00069 template <class SolvingAlgorithmType>
00070 FCSDFSSolvingAlgorithm<SolvingAlgorithmType>::~FCSDFSSolvingAlgorithm()
00071 {
00072 }
00073 
00074 template <class SolvingAlgorithmType>
00075 FCSStateSolvingReturnCodes FCSDFSSolvingAlgorithm<SolvingAlgorithmType>::Solve(FCSStateWithLocations* StateWithLocations, int Depth)
00076 {
00077     FCSStateSolvingReturnCodes Check;
00078 
00079     int NumberOfIterations = m_NumberOfCheckedStates,
00080         NumberOfFreeStacks = 0, 
00081         NumberOfFreecells = 0,
00082         a;
00083 
00084     FCSDerivedStatesList Derived;
00085 
00086     //DFS is the only solving method that calls Solve() recursively and
00087     //InitSolve is meant to be only called once.
00088     if (!m_IsInitialized)
00089     {
00090         InitSolve(StateWithLocations);
00091         m_IsInitialized = true;
00092     }
00093 
00094     /*
00095      * If this state has not been visited before - increase the number of
00096      * iterations this program has seen, and output this state again.
00097      *
00098      * I'm doing this in order to make the output of a stopped and
00099      * resumed run consistent with the output of a normal (all-in-one-time)
00100      * run.
00101      * */
00102     if (!(StateWithLocations->m_Visited & FCS_VISITED_VISITED))
00103     {
00104         m_DebugDisplayInfo->Display(m_StateType, m_NumberOfCheckedStates, Depth, 
00105                                     StateWithLocations, 0, m_NumberOfStatesInCollection);
00106 
00107         // Increase the number of iterations
00108         m_NumberOfCheckedStates++;
00109         StateWithLocations->m_VisitIterations = NumberOfIterations;
00110     }
00111 
00112     // Mark this state as visited, so it won't be recursed into again.
00113     StateWithLocations->m_Visited |= FCS_VISITED_VISITED;
00114 
00115     // Count the free-cells
00116     for(a=0;a<m_NumberOfFreecells;a++)
00117     {
00118         if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00119             NumberOfFreecells++;
00120     }
00121 
00122     // Count the number of unoccupied stacks
00123     for(a=0;a<m_NumberOfStacks;a++)
00124     {
00125         if (StateWithLocations->GetStackLength(a) == 0)
00126             NumberOfFreeStacks++;
00127     }
00128 
00129 
00130     // Let's check if this state is finished, and if so return 0;
00131     if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00132     {
00133         m_FinalState = StateWithLocations;
00134         DeleteDerived(&Derived);
00135         return FCS_STATE_WAS_SOLVED;
00136     }
00137 
00138     for(a=0; a < m_TestsOrderNumber; a++)
00139     {
00140         Derived.m_NumberOfStates = 0;
00141 
00142         Check = RunTest(m_TestsOrder[a] & FCS_TEST_ORDER_NO_FLAGS_MASK, StateWithLocations, Depth, NumberOfFreeStacks,
00143                         NumberOfFreecells, &Derived);
00144 
00145         if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00146             (Check == FCS_STATE_SUSPEND_PROCESS))
00147         {
00148             if (Check == FCS_STATE_BEGIN_SUSPEND_PROCESS)
00149             {
00150                 m_NumberOfSolutionStates = Depth+1;
00151 
00152                 m_SolutionStates = CreateStateWithLocationsMatrix(m_NumberOfSolutionStates);
00153                 m_ProtoSolutionMoves = new FCSMoveStack*[m_NumberOfSolutionStates-1];
00154             }
00155 
00156             m_SolutionStates->Set(Depth, StateWithLocations);
00157 
00158             DeleteDerived(&Derived);
00159             return FCS_STATE_SUSPEND_PROCESS;
00160         }
00161 
00162         for(int DerivedStateIndex=0; DerivedStateIndex<Derived.m_NumberOfStates; DerivedStateIndex++)
00163         {
00164             if (!Derived.m_States[DerivedStateIndex]->m_Visited)
00165             {
00166                 Check = Solve(Derived.m_States[DerivedStateIndex], Depth+1);
00167 
00168                 if ((Check == FCS_STATE_SUSPEND_PROCESS) ||
00169                     (Check == FCS_STATE_BEGIN_SUSPEND_PROCESS))
00170                 {
00171                     m_SolutionStates->Set(Depth, StateWithLocations);
00172 
00173                     DeleteDerived(&Derived);
00174                     return FCS_STATE_SUSPEND_PROCESS;
00175                 }
00176 
00177                 if (Check == FCS_STATE_WAS_SOLVED)
00178                 {
00179                     DeleteDerived(&Derived);
00180                     return FCS_STATE_WAS_SOLVED;
00181                 }
00182             }
00183         }
00184     }
00185 
00186     DeleteDerived(&Derived);
00187 
00188     return FCS_STATE_IS_NOT_SOLVEABLE;
00189 }
00190 
00191 template <class SolvingAlgorithmType>
00192 FCSStateSolvingReturnCodes FCSDFSSolvingAlgorithm<SolvingAlgorithmType>::Resume(int Depth)
00193 {
00194     FCSStateWithLocations* StateWithLocations = m_SolutionStates->Get(Depth, 0);
00195     FCSMoveStack* Moves = NULL;
00196 
00197     FCSStateSolvingReturnCodes Check;
00198 
00199     bool UseOwnMoves = true;
00200 
00201     if (Depth < m_NumberOfSolutionStates-1)
00202     {
00203         Check = Resume(Depth+1);
00204     }
00205     else
00206     {
00207         delete [] m_SolutionStates;
00208         m_SolutionStates = NULL;
00209         delete [] m_ProtoSolutionMoves;
00210         m_ProtoSolutionMoves = NULL;
00211         Check = FCS_STATE_IS_NOT_SOLVEABLE;
00212     }
00213 
00214     switch(Check)
00215     {
00216     case FCS_STATE_IS_NOT_SOLVEABLE:
00217         Check = Solve(StateWithLocations, Depth);
00218         break;
00219     case FCS_STATE_WAS_SOLVED:
00220         break;
00221     case FCS_STATE_SUSPEND_PROCESS:
00222         m_SolutionStates->Set(Depth, StateWithLocations);
00223         break;
00224     }
00225 
00226     return Check;
00227 }
00228 
00229 #endif

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