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
00087
00088 if (!m_IsInitialized)
00089 {
00090 InitSolve(StateWithLocations);
00091 m_IsInitialized = true;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
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
00108 m_NumberOfCheckedStates++;
00109 StateWithLocations->m_VisitIterations = NumberOfIterations;
00110 }
00111
00112
00113 StateWithLocations->m_Visited |= FCS_VISITED_VISITED;
00114
00115
00116 for(a=0;a<m_NumberOfFreecells;a++)
00117 {
00118 if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00119 NumberOfFreecells++;
00120 }
00121
00122
00123 for(a=0;a<m_NumberOfStacks;a++)
00124 {
00125 if (StateWithLocations->GetStackLength(a) == 0)
00126 NumberOfFreeStacks++;
00127 }
00128
00129
00130
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