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
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
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
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
00170 if (Depth+1 >= m_DFSMaxDepth)
00171 IncreaseDFSMaxDepth();
00172
00173
00174 if (m_SoftDFSCurrentStateIndexes[Depth] == m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates)
00175 {
00176 if (m_SoftDFSTestIndexes[Depth] >= m_TestsOrderNumber)
00177 {
00178
00179 Depth--;
00180 continue;
00181 }
00182
00183 m_SoftDFSDerivedStatesLists[Depth].m_NumberOfStates = 0;
00184 StateWithLocations = m_SolutionStates->Get(Depth, 0);
00185
00186
00187
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
00197 for(a=0;a<m_NumberOfFreecells;a++)
00198 {
00199 if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00200 NumberOfFreecells++;
00201 }
00202
00203
00204 for(a=0;a<m_NumberOfStacks;a++)
00205 {
00206 if (StateWithLocations->GetStackLength(a) == 0)
00207 NumberOfFreeStacks++;
00208 }
00209
00210
00211 if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00212 {
00213 m_FinalState = StateWithLocations;
00214 return FCS_STATE_WAS_SOLVED;
00215 }
00216
00217
00218
00219
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
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
00246 m_SoftDFSTestIndexes[Depth]++;
00247 }
00248
00249
00250
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
00270
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
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