00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FCSTalonSolvingAlgorithm.h"
00010 #include "FCSAStarSolvingAlgorithm.h"
00011 #include "FCSBFSSolvingAlgorithm.h"
00012 #include "FCSDFSSolvingAlgorithm.h"
00013 #include "FCSRandomDFSSolvingAlgorithm.h"
00014 #include "FCSSoftDFSSolvingAlgorithm.h"
00015
00016 FCSTalonSolvingAlgorithm::FCSTalonSolvingAlgorithm() : FCSFreecellSolvingAlgorithm()
00017 {
00018 InitFCSTalonSolvingAlgorithm();
00019 }
00020
00021 FCSTalonSolvingAlgorithm::FCSTalonSolvingAlgorithm(FCCommandLineArguments* CommandLine) : FCSFreecellSolvingAlgorithm(CommandLine)
00022 {
00023 InitFCSTalonSolvingAlgorithm();
00024
00025 m_TalonType = CommandLine->GetTalonType();
00026 }
00027
00028 void FCSTalonSolvingAlgorithm::InitFCSTalonSolvingAlgorithm()
00029 {
00030 m_TalonType = FCS_TALON_NONE;
00031 m_TalonsHash = NULL;
00032 }
00033
00034 FCSTalonSolvingAlgorithm::~FCSTalonSolvingAlgorithm()
00035 {
00036 if (m_TalonsHash != NULL)
00037 {
00038 m_TalonsHash->DeleteItems();
00039 delete m_TalonsHash;
00040 }
00041 }
00042
00043 FCSTalonSolvingAlgorithm* FCSTalonSolvingAlgorithm::Create(FCCommandLineArguments* CommandLine)
00044 {
00045
00046 if (CommandLine == NULL)
00047 return NULL;
00048
00049
00050 switch(CommandLine->GetSolvingMethodType())
00051 {
00052 case FCS_METHOD_HARD_DFS:
00053 return new FCSDFSSolvingAlgorithm<FCSTalonSolvingAlgorithm>(CommandLine);
00054 case FCS_METHOD_SOFT_DFS:
00055 return new FCSSoftDFSSolvingAlgorithm<FCSTalonSolvingAlgorithm>(CommandLine);
00056 case FCS_METHOD_BFS:
00057 return new FCSBFSSolvingAlgorithm<FCSTalonSolvingAlgorithm>(CommandLine);
00058 case FCS_METHOD_A_STAR:
00059 return new FCSAStarSolvingAlgorithm<FCSTalonSolvingAlgorithm>(CommandLine);
00060 case FCS_METHOD_RANDOM_DFS:
00061 return new FCSRandomDFSSolvingAlgorithm<FCSTalonSolvingAlgorithm>(CommandLine);
00062 default:
00063 return NULL;
00064 }
00065
00066 return NULL;
00067 }
00068
00069 FCSStateSolvingReturnCodes FCSTalonSolvingAlgorithm::RunTest(int TestNumber, FCSStateWithLocations* StateWithLocations,
00070 int Depth, int NumberOfFreeStacks,
00071 int NumberOfFreecells,
00072 FCSDerivedStatesList* DerivedStateList)
00073 {
00074 switch(TestNumber)
00075 {
00076 case 0:
00077 return MoveTopStackCardsToFounds(StateWithLocations, Depth, NumberOfFreeStacks,
00078 NumberOfFreecells, DerivedStateList);
00079 case 1:
00080 return MoveNonTopStackCardsToFounds(StateWithLocations, Depth, NumberOfFreeStacks,
00081 NumberOfFreecells, DerivedStateList);
00082 case 2:
00083 return MoveStackCardsToDifferentStacks(StateWithLocations, Depth, NumberOfFreeStacks,
00084 NumberOfFreecells, DerivedStateList);
00085 case 3:
00086 return MoveStackCardsToAParentOnTheSameStack(StateWithLocations, Depth, NumberOfFreeStacks,
00087 NumberOfFreecells, DerivedStateList);
00088 case 4:
00089 return MoveSequencesToFreeStacks(StateWithLocations, Depth, NumberOfFreeStacks,
00090 NumberOfFreecells, DerivedStateList);
00091 case 5:
00092 return MoveCardsToADifferentParent(StateWithLocations, Depth, NumberOfFreeStacks,
00093 NumberOfFreecells, DerivedStateList);
00094 case 6:
00095 return GetCardFromKlondikeTalon(StateWithLocations, Depth, NumberOfFreeStacks,
00096 NumberOfFreecells, DerivedStateList);
00097 default:
00098 return FCS_STATE_IS_NOT_SOLVEABLE;
00099 }
00100 }
00101
00102 void FCSTalonSolvingAlgorithm::InitSolve(FCSStateWithLocations* InitState)
00103 {
00104
00105 if (m_TalonType == FCS_TALON_KLONDIKE)
00106 {
00107 m_TalonsHash = new FCInternalHash<FCSTalonStateData, void>(TALON_CACHE_SIZE,
00108 &m_TalonCompareFunction, &m_TalonHashFunction, DELETE_HASH_ITEM);
00109 }
00110
00111 FCSFreecellData::InitSolve(InitState);
00112 }
00113
00114 FCSStateSolvingReturnCodes FCSTalonSolvingAlgorithm::CheckAndAddState(FCSStateWithLocations* NewState,
00115 FCSStateWithLocations** ExistingState,
00116 int Depth)
00117 {
00118 if (((m_MaxNumberOfCheckedStates >= 0) &&
00119 (m_NumberOfCheckedStates >= m_MaxNumberOfCheckedStates)) ||
00120 ((m_MaxNumberOfStatesInCollection >= 0) &&
00121 (m_NumberOfStatesInCollection >= m_MaxNumberOfStatesInCollection)))
00122 {
00123 return FCS_STATE_BEGIN_SUSPEND_PROCESS;
00124 }
00125
00126 if ((m_MaxDepth >= 0) &&
00127 (m_MaxDepth <= Depth))
00128 {
00129 return FCS_STATE_EXCEEDS_MAX_DEPTH;
00130 }
00131
00132 NewState->CanonizeState(m_NumberOfFreecells, m_NumberOfStacks);
00133 NewState->CacheStacks(m_StackStorage, m_NumberOfStacks);
00134 ((FCSTalonStateWithLocations*)NewState)->CacheTalonStacks(m_TalonsHash);
00135
00136 if (m_StateStorage->CheckAndInsert(ExistingState, NewState))
00137 {
00138
00139 m_NumberOfStatesInCollection++;
00140 return FCS_STATE_DOES_NOT_EXIST;
00141 }
00142
00143 return FCS_STATE_ALREADY_EXISTS;
00144 }
00145
00146 FCSStateSolvingReturnCodes FCSTalonSolvingAlgorithm::GetCardFromKlondikeTalon(FCSStateWithLocations* StateWithLocations,
00147 int Depth,
00148 int NumberOfFreeStacks,
00149 int NumberOfFreecells,
00150 FCSDerivedStatesList* DerivedStateList)
00151 {
00152 if (m_TalonType != FCS_TALON_KLONDIKE)
00153 {
00154 return FCS_STATE_IS_NOT_SOLVEABLE;
00155 }
00156
00157 FCSStateWithLocations *NewStateWithLocations;
00158 FCSTalonStateData* TempTalonData = CreateTalonStateData();
00159 FCSMoveStack *Moves = CreateMoveStack();
00160 FCSMove *TempMove = FCSMove::Create();
00161
00162 FCSStateSolvingReturnCodes Check;
00163 int NumberOfRedealsDone = 0,
00164 NumberOfCardsMoved[2] = {0,0};
00165
00166 bool FirstIteration = true;
00167
00168 FCSCard *CardToCheck = FCSCard::Create(),
00169 *TopCard = FCSCard::Create();
00170
00171
00172 TempTalonData->Copy(((FCSTalonStateWithLocations*)StateWithLocations)->GetTalonData());
00173
00174 char SavedStackPosition = TempTalonData->GetKlondikeTalonStackPosition();
00175
00176
00177 int NumberOfRedealsLeft = TempTalonData->GetKlondikeNumberOfRedealsLeft();
00178 if (NumberOfRedealsLeft != 0)
00179 NumberOfRedealsLeft = 1;
00180
00181 while (NumberOfRedealsLeft >= 0)
00182 {
00183 if ((TempTalonData->GetKlondikeTalonStackPosition() == -1) &&
00184 (TempTalonData->GetKlondikeTalonQueuePosition() == TempTalonData->GetKlondikeTalonLength()))
00185 break;
00186
00187 if ((!FirstIteration) || (TempTalonData->GetKlondikeTalonStackPosition() == -1))
00188 {
00189 if (TempTalonData->GetKlondikeTalonStackPosition() == TempTalonData->GetKlondikeTalonLength() - 1)
00190 {
00191 if (NumberOfRedealsLeft > 0)
00192 {
00193
00194 TempTalonData->KlondikeTalonRedealBare();
00195
00196 NumberOfRedealsLeft--;
00197 NumberOfRedealsDone++;
00198 }
00199 else
00200 {
00201 break;
00202 }
00203 }
00204 else if ((NumberOfRedealsLeft <= 0) &&
00205 (TempTalonData->GetKlondikeTalonStackPosition() >= SavedStackPosition - 1))
00206 {
00207 break;
00208 }
00209
00210 TempTalonData->KlondikeTalonQueueToStack();
00211 NumberOfCardsMoved[NumberOfRedealsDone]++;
00212 }
00213
00214 FirstIteration = false;
00215
00216 CardToCheck->Copy(TempTalonData->GetKlondikeTalonTopCard());
00217 if (CardToCheck->IsEmptyCard())
00218 continue;
00219
00220
00221 for(int Deck=0;Deck < m_NumberOfDecks;Deck++)
00222 {
00223 if (StateWithLocations->GetFoundation(Deck*4 + CardToCheck->GetSuit()) != CardToCheck->GetCardNumber() - 1)
00224 continue;
00225
00226
00227 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00228
00229 ((FCSTalonStateWithLocations*)NewStateWithLocations)->GetTalonData()->Copy(TempTalonData);
00230
00231 for(int a=0;a<=NumberOfRedealsDone;a++)
00232 {
00233 TempMove->SetType(FCS_MOVE_TYPE_KLONDIKE_FLIP_TALON);
00234 TempMove->SetNumberOfCardsFlipped(NumberOfCardsMoved[a]);
00235 Moves->Push(TempMove);
00236 if (a != NumberOfRedealsDone)
00237 {
00238 TempMove->SetType(FCS_MOVE_TYPE_KLONDIKE_REDEAL_TALON);
00239 Moves->Push(TempMove);
00240 }
00241 }
00242
00243 NewStateWithLocations->IncrementFoundation(Deck*4+CardToCheck->GetSuit());
00244 ((FCSTalonStateWithLocations*)NewStateWithLocations)->DecrementKlondikeTalonStack();
00245
00246 TempMove->SetType(FCS_MOVE_TYPE_KLONDIKE_TALON_TO_FOUNDATION);
00247 TempMove->SetFoundation(Deck*4+CardToCheck->GetSuit());
00248 Moves->Push(TempMove);
00249
00250
00251
00252
00253
00254
00255 TempMove->SetType(FCS_MOVE_TYPE_CANONIZE);
00256 Moves->Push(TempMove);
00257
00258 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00259 &Moves, &TempMove, Depth, &Check))
00260 {
00261 delete TempTalonData;
00262 delete [] Moves;
00263 delete TempMove;
00264 delete CardToCheck;
00265 delete TopCard;
00266 return Check;
00267 }
00268
00269 break;
00270 }
00271
00272
00273 for(int Stack=0; Stack<m_NumberOfStacks; Stack++)
00274 {
00275 TopCard->Copy(StateWithLocations->GetStackCard(Stack, StateWithLocations->GetStackLength(Stack)-1));
00276
00277 if ((!IsParentCard(CardToCheck, TopCard)) &&
00278 ((StateWithLocations->GetStackLength(Stack) > 0) ||
00279 (m_EmptyStacksFill == FCS_ES_FILLED_BY_NONE) ||
00280 ((m_EmptyStacksFill == FCS_ES_FILLED_BY_KINGS_ONLY) && (CardToCheck->GetCardNumber() != 13))
00281 )
00282 )
00283 continue;
00284
00285
00286 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00287
00288 ((FCSTalonStateWithLocations*)NewStateWithLocations)->GetTalonData()->Copy(TempTalonData);
00289
00290 for(int a=0;a<=NumberOfRedealsDone;a++)
00291 {
00292 TempMove->SetType(FCS_MOVE_TYPE_KLONDIKE_FLIP_TALON);
00293 TempMove->SetNumberOfCardsFlipped(NumberOfCardsMoved[a]);
00294 Moves->Push(TempMove);
00295 if (a != NumberOfRedealsDone)
00296 {
00297 TempMove->SetType(FCS_MOVE_TYPE_KLONDIKE_REDEAL_TALON);
00298 Moves->Push(TempMove);
00299 }
00300 }
00301
00302 NewStateWithLocations->PushCardIntoStack(Stack, ((FCSTalonStateWithLocations*)NewStateWithLocations)->GetTalonData()->GetKlondikeTalonTopCard());
00303 ((FCSTalonStateWithLocations*)NewStateWithLocations)->DecrementKlondikeTalonStack();
00304
00305 TempMove->SetType(FCS_MOVE_TYPE_KLONDIKE_TALON_TO_STACK);
00306 TempMove->SetDestStack(Stack);
00307 Moves->Push(TempMove);
00308
00309 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00310 &Moves, &TempMove, Depth, &Check))
00311 {
00312 delete TempTalonData;
00313 delete [] Moves;
00314 delete TempMove;
00315 delete CardToCheck;
00316 delete TopCard;
00317 return Check;
00318 }
00319 }
00320 }
00321
00322 delete TempTalonData;
00323 delete [] Moves;
00324 delete TempMove;
00325 delete CardToCheck;
00326 delete TopCard;
00327
00328 return FCS_STATE_IS_NOT_SOLVEABLE;
00329 }