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

FCSFreecellData.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "FCSFreecellData.h"
00010 
00011 
00012 #include "FCSTalonStateWithLocations.h"
00013 
00014 FCSFreecellData::FCSFreecellData()
00015 {
00016     InitFCSFreecellData();
00017 }
00018 
00019 void FCSFreecellData::InitFCSFreecellData()
00020 {
00021     IsOptimizeClass = false;
00022 
00023     m_StateType = DEFAULT_STATE_TYPE;
00024 
00025     m_StatePacks = NULL;
00026     m_MaxNumberOfStatePacks = 0;
00027     m_NumberOfStatePacks = 0;
00028     m_NumberOfStatesInLastPack = 0;
00029     m_StatePackLength = 0;
00030 
00031     m_NumberOfCheckedStates = 0;
00032     m_SolutionStates = NULL;
00033     m_NumberOfSolutionStates = 0;
00034 
00035     m_SolutionMoves = NULL;
00036     m_ProtoSolutionMoves = NULL;
00037 
00038     m_NumberOfStatesInCollection = 0;
00039     m_MaxNumberOfStatesInCollection = -1;
00040 
00041     m_MaxDepth = -1;
00042     m_MaxNumberOfCheckedStates = -1;
00043 
00044     m_DebugDisplayInfo = NULL;
00045 
00046     m_TestsOrderNumber = FCS_TESTS_NUM;
00047     for(int a=0;a<FCS_TESTS_NUM;a++)
00048         m_TestsOrder[a] = a;
00049 
00050     m_StateStorage = NULL;
00051     m_StackStorage = NULL;
00052 
00053     m_NumberOfFreecells = DEFAULT_NUMBER_OF_FREECELLS;
00054     m_NumberOfStacks = DEFAULT_NUMBER_OF_STACKS;
00055     m_NumberOfDecks = DEFAULT_NUMBER_OF_DECKS;
00056 
00057     m_SequencesAreBuiltBy = DEFAULT_BUILD_SEQUENCE_TYPE;
00058     m_IsUnlimitedSequenceMove = false;
00059     m_EmptyStacksFill = DEFAULT_EMPTY_STACK_FILL_TYPE;
00060 
00061     m_OptimizeSolutionPath = false;
00062 
00063     //****** I'm not quite sure where to put these, so they're here for now *****
00064     //****** Since they vary, should they all be pointers and allocated only if needed ?  *****
00065     m_IndirectCompare = NULL;
00066     m_IndirectHash = NULL;
00067 }
00068 
00069 FCSFreecellData::FCSFreecellData(FCCommandLineArguments* CommandLine)
00070 {
00071     InitFCSFreecellData();
00072 
00073     //get state type (Debug, Compact, Indirect)
00074     m_StateType = CommandLine->GetStateType();
00075 
00076     //initialize state packs
00077     m_MaxNumberOfStatePacks = IA_STATE_PACKS_GROW_BY;
00078     m_StatePacks = CreateStateWithLocationsMatrix(m_MaxNumberOfStatePacks);
00079     m_NumberOfStatePacks = 1;
00080     m_NumberOfStatesInLastPack = 0;
00081     m_StatePackLength = FC_MAX_STATE_PACK_LENGTH / GetFCSStateWithLocationsClassSize();
00082     m_StatePacks->CreateArray(0, m_StatePackLength);
00083 
00084     m_MaxNumberOfStatesInCollection = CommandLine->GetMaxStoredStates();
00085     m_MaxDepth = CommandLine->GetMaxDepth();
00086     m_MaxNumberOfCheckedStates = CommandLine->GetMaxNumberOfIterations();
00087 
00088     if (CommandLine->GetNumberOfTests() > 0)
00089     {
00090         // Initialize the test order
00091         if (CommandLine->GetTestOrderNumber(0) != NULL)
00092         {
00093             int b;
00094             for (b = 0;CommandLine->GetTestOrderNumber(b) != NULL;b++)
00095                 m_TestsOrder[b] = CommandLine->GetTestOrderNumber(b);
00096 
00097             m_TestsOrderNumber = b;
00098         }
00099     }
00100 
00101 //*****  The HASH_TABLE_SIZE parameter may be abandoned for a user-controlled value
00102 
00103     //create state and stack storage
00104     switch(CommandLine->GetStateStorageType())
00105     {
00106     case FC_AVL_TREE:
00107         m_StateStorage = new FCAVLTreeStateStorage(&m_CompareFunction);
00108         break;
00109     case FC_AVL_RED_BLACK_TREE:
00110         m_StateStorage = new FCAVLRedBlackTreeStateStorage(&m_CompareFunction);
00111         break;
00112     case FC_RED_BLACK_TREE:
00113         m_StateStorage = new FCRedBlackTreeStateStorage(&m_CompareFunction);
00114         break;
00115     case FC_GLIB_TREE:
00116         m_StateStorage = new FCGLIBTreeStateStorage(&m_CompareFunction);
00117         break;
00118     case FC_GLIB_HASH:
00119         m_StateStorage = new FCGLIBHashStateStorage(HASH_TABLE_SIZE, &m_CompareFunction, &m_MD5Hash);
00120         break;
00121     case FC_INTERNAL_HASH:
00122         m_StateStorage = new FCInternalHashStateStorage(HASH_TABLE_SIZE, &m_CompareFunction, &m_MD5Hash);
00123         break;
00124     case FC_INDIRECT_HASH:
00125         m_StateStorage = new FCIndirectStateStorage();
00126             break;
00127     default:
00128         m_StateStorage = NULL;
00129     }
00130 
00131     if ((m_StateType == FC_INDIRECT_STATE) || (m_StateType == FC_TALON_INDIRECT_STATE))
00132     {
00133         m_IndirectCompare = new FCSIndirectCardCompareAlgorithm<FCSIndirectCard, void>();
00134         m_IndirectHash = new MD5HashAlgorithm<FCSIndirectCard>();
00135 
00136         switch(CommandLine->GetStackStorageType())
00137         {
00138         case FC_AVL_TREE:
00139             m_StackStorage = new FCAVLTreeStackStorage(m_IndirectCompare);
00140             break;
00141         case FC_AVL_RED_BLACK_TREE:
00142             m_StackStorage = new FCAVLRedBlackTreeStackStorage(m_IndirectCompare);
00143             break;
00144         case FC_RED_BLACK_TREE:
00145             m_StackStorage = new FCRedBlackTreeStackStorage(m_IndirectCompare);
00146             break;
00147         case FC_GLIB_TREE:
00148             m_StackStorage = new FCGLIBTreeStackStorage(m_IndirectCompare);
00149             break;
00150         case FC_GLIB_HASH:
00151             m_StackStorage = new FCGLIBHashStackStorage(HASH_TABLE_SIZE, m_IndirectCompare, m_IndirectHash);
00152             break;
00153         case FC_INTERNAL_HASH:
00154             m_StackStorage = new FCInternalHashStackStorage(HASH_TABLE_SIZE, m_IndirectCompare, m_IndirectHash);
00155             break;
00156         default:
00157             m_StackStorage = NULL;
00158         }
00159     }
00160 
00161     m_DebugDisplayInfo = CommandLine->GetDebugDisplayInfo();
00162     m_NumberOfFreecells = CommandLine->GetNumberOfFreecells();
00163     m_NumberOfStacks = CommandLine->GetNumberOfStacks();
00164     m_NumberOfDecks = CommandLine->GetNumberOfDecks();
00165 
00166     m_SequencesAreBuiltBy = CommandLine->GetSequenceBuildType();
00167 
00168     m_IsUnlimitedSequenceMove = CommandLine->GetIsSequenceMoveUnlimited();
00169     m_EmptyStacksFill = CommandLine->GetEmptyStacksFill();
00170 
00171     m_OptimizeSolutionPath = CommandLine->GetOptimizeSolution();
00172 }
00173 
00174 FCSFreecellData::~FCSFreecellData()
00175 {   
00176     if (!IsOptimizeClass)
00177     {
00178         int p,s;
00179         for(p=0; p<m_NumberOfStatePacks-1;p++)
00180             for(s=0 ; s < m_StatePackLength ; s++)
00181                 m_StatePacks->DeleteStateWithLocationsParent(p, s);
00182 
00183         for(s=0; s < m_NumberOfStatesInLastPack ; s++)
00184             m_StatePacks->DeleteStateWithLocationsParent(p, s);
00185 
00186         // De-allocate the state packs  - fcs_state_ia_finish(instance);
00187         for(int a=0;a<m_NumberOfStatePacks;a++)
00188             m_StatePacks->DeleteArray(a);
00189 
00190         delete m_StatePacks;
00191 
00192         delete m_StateStorage;
00193         delete m_StackStorage;
00194 
00195         if (m_IndirectCompare != NULL)
00196             delete m_IndirectCompare;
00197 
00198         if (m_IndirectHash != NULL)
00199             delete m_IndirectHash;
00200 
00201         if (m_DebugDisplayInfo != NULL)
00202             delete m_DebugDisplayInfo;
00203     }
00204 
00205     if (m_ProtoSolutionMoves != NULL)
00206     {
00207         delete [] m_ProtoSolutionMoves;
00208         m_ProtoSolutionMoves = NULL;
00209     }
00210 
00211     if (m_SolutionMoves != NULL)
00212     {
00213         delete [] m_SolutionMoves;
00214         m_SolutionMoves = NULL;
00215     }
00216 
00217     if (m_SolutionStates != NULL)
00218     {
00219         delete [] m_SolutionStates;
00220         m_SolutionStates = NULL;
00221     }
00222 
00223 }
00224 
00225 void FCSFreecellData::InitSolve(FCSStateWithLocations* InitState)
00226 {
00227     // Allocate the first state and initialize it to init_state
00228     FCSStateWithLocations *NoUse = NULL;
00229 
00230     //putting in a dummy state
00231     CheckAndAddState(InitState, &NoUse, 0);
00232 }
00233 
00234 void FCSFreecellData::CleanData()
00235 {
00236     for(int a=0;a<m_NumberOfSolutionStates-1;a++)
00237     {
00238         m_SolutionStates->Get(a, 0)->CleanState();
00239         m_SolutionStates->DeleteArray(a);
00240         delete m_ProtoSolutionMoves[a];
00241     }
00242 
00243     delete [] m_SolutionStates;
00244     m_SolutionStates = NULL;
00245 
00246     delete [] m_ProtoSolutionMoves;
00247     m_ProtoSolutionMoves = NULL;
00248 }
00249 
00250 void FCSFreecellData::ShowSolution(FCSStateWithLocations* InitStateWithLocations, 
00251                                    FCSStateWithLocations* DupStateWithLocations)
00252 {
00253     //Combine the move stacks of every depth to one big move stack.
00254     CreateTotalMovesStack();
00255 
00256     for(int a=0;a<m_NumberOfSolutionStates;a++)
00257     {
00258         m_SolutionStates->Get(a, 0)->CleanState();
00259         m_SolutionStates->Delete(a);
00260     }
00261 
00262     delete [] m_SolutionStates;
00263     m_SolutionStates = NULL;
00264 
00265     m_SolutionMoves->Normalize(InitStateWithLocations, m_NumberOfFreecells, m_NumberOfStacks, m_NumberOfDecks);
00266 
00267     FCSMove* Move = FCSMove::Create();
00268     char AsString[STATE_STRING_SIZE];
00269     int NumberOfMoves = 0;
00270     
00271     if (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_DISPLAY_STATES)
00272     {
00273         cout << "-=-=-=-=-=-=-=-=-=-=-=-" << endl << endl;
00274         DupStateWithLocations->StateAsString(AsString, m_DebugDisplayInfo);
00275         cout << AsString << endl << endl << "====================" << endl << endl;
00276     }
00277 
00278     while (GetNextMove(DupStateWithLocations, Move) == 0)
00279     {
00280         if (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_DISPLAY_MOVES)
00281         {
00282             (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_USE_STANDARD_NOTATION) ?
00283                     Move->MoveAsStringStandardNotation(AsString) :
00284                     Move->MoveAsString(AsString);
00285 
00286             if (m_DebugDisplayInfo->m_DisplayDebugOptions & (DEBUG_DISPLAY_STATES | DEBUG_USE_STANDARD_NOTATION))
00287                 cout << "Move: ";
00288 
00289             NumberOfMoves++;
00290 
00291             cout << NumberOfMoves << ":\t" << AsString 
00292                  << ((m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_USE_STANDARD_NOTATION) ? " " : "\n");
00293 
00294             if ((m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_USE_STANDARD_NOTATION) &&
00295                 ((NumberOfMoves % 10 == 0) || (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_DISPLAY_STATES)))
00296                 cout << endl;
00297 
00298             if (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_DISPLAY_STATES)
00299                 cout << endl;
00300         }
00301 
00302         if (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_DISPLAY_STATES)
00303         {
00304             DupStateWithLocations->StateAsString(AsString, m_DebugDisplayInfo);
00305             cout << AsString << endl;
00306         }
00307 
00308         if (m_DebugDisplayInfo->m_DisplayDebugOptions & (DEBUG_DISPLAY_STATES | (!DEBUG_USE_STANDARD_NOTATION)))
00309             cout << endl << "====================" << endl << endl;
00310     }
00311 
00312     if (m_DebugDisplayInfo->m_DisplayDebugOptions & (DEBUG_USE_STANDARD_NOTATION | (!DEBUG_DISPLAY_STATES )))
00313         cout << endl << endl;
00314 
00315     delete Move;
00316 }
00317 
00318 void FCSFreecellData::TraceSolution()
00319 {
00320     //  Trace the solution.
00321     FCSStateWithLocations* State = m_FinalState;
00322 
00323     // The depth of the last state reached is the number of them
00324     m_NumberOfSolutionStates = State->m_Depth+1;
00325 
00326     if (m_SolutionStates != NULL)
00327         delete [] m_SolutionStates;
00328 
00329     if (m_ProtoSolutionMoves != NULL)
00330         delete [] m_ProtoSolutionMoves;
00331 
00332     // Allocate space for the solution stacks
00333     m_SolutionStates = CreateStateWithLocationsMatrix(m_NumberOfSolutionStates);
00334     m_ProtoSolutionMoves = new FCSMoveStack*[m_NumberOfSolutionStates-1];
00335 
00336     // Retrace the step from the current state to its parents
00337     while (State->m_Parent != NULL)
00338     {
00339         // Mark the state as part of the non-optimized solution
00340         State->m_Visited |= FCS_VISITED_IN_SOLUTION_PATH;
00341 
00342         // Duplicate the move stack
00343         m_ProtoSolutionMoves[State->m_Depth-1] = State->m_MovesToParent->Copy();
00344 
00345         // Duplicate the state to a freshly malloced memory
00346         m_SolutionStates->Create(State->m_Depth);
00347         m_SolutionStates->Get(State->m_Depth, 0)->Copy(State);
00348 
00349         // Move to the parent state
00350         State = State->m_Parent;
00351     }
00352 
00353     // There's one more state than there are move stacks
00354     State->m_Visited |= FCS_VISITED_IN_SOLUTION_PATH;
00355     m_SolutionStates->Create(0);
00356     m_SolutionStates->Get(0, 0)->Copy(State);
00357 }
00358 
00359 int FCSFreecellData::GetNumberOfCheckedStates()
00360 {
00361     return m_NumberOfCheckedStates;
00362 }
00363 
00364 int FCSFreecellData::GetNumberOfStatesInCollection()
00365 {
00366     return m_NumberOfStatesInCollection;
00367 }
00368 
00369 void FCSFreecellData::IncreaseMaxNumberOfCheckedStates()
00370 {
00371     m_MaxNumberOfCheckedStates += 10;
00372 }
00373 
00374 int FCSFreecellData::GetNextMove(FCSStateWithLocations* StateWithLocations, FCSMove* Move)
00375 {
00376     int ReturnValue = m_SolutionMoves->Pop(&Move);
00377 
00378     if (ReturnValue == 0)
00379     {
00380         ApplyMove(StateWithLocations, Move, m_NumberOfFreecells, 
00381                     m_NumberOfStacks, m_NumberOfDecks); 
00382     }
00383 
00384     return ReturnValue;
00385 }
00386 
00387 void FCSFreecellData::CreateTotalMovesStack()
00388 {
00389     int Depth;
00390     m_SolutionMoves = CreateMoveStack();
00391 
00392     // The moves are inserted from the highest depth to depth 0 in order
00393     // to preserve their order stack-wise 
00394 
00395     if (m_DebugDisplayInfo->m_DisplayDebug)
00396     {
00397         int Sum = 0;
00398         for(Depth=0 ; Depth <= m_NumberOfSolutionStates-2 ; Depth++)
00399         {
00400             Sum += m_ProtoSolutionMoves[Depth]->GetNumberOfMoves();
00401             cout << "Depth " << Depth << " : " << Sum << endl;
00402         }
00403     }
00404 
00405     for(Depth=m_NumberOfSolutionStates-2;Depth>=0;Depth--)
00406         m_SolutionMoves->SwallowStack(m_ProtoSolutionMoves[Depth]);
00407 
00408     delete [] m_ProtoSolutionMoves;
00409     m_ProtoSolutionMoves = NULL;
00410 }
00411 
00412 //fcs_state_ia_alloc
00413 FCSStateWithLocations* FCSFreecellData::StatePackAlloc()
00414 {
00415     if (m_NumberOfStatesInLastPack == m_StatePackLength)
00416     {
00417         if (m_NumberOfStatePacks == m_MaxNumberOfStatePacks)
00418         {
00419             m_MaxNumberOfStatePacks += IA_STATE_PACKS_GROW_BY;
00420             m_StatePacks->ReallocArray(m_NumberOfStatePacks, m_MaxNumberOfStatePacks);
00421         }
00422         m_StatePacks->CreateArray(m_NumberOfStatePacks, m_StatePackLength);
00423         m_NumberOfStatePacks++;
00424         m_NumberOfStatesInLastPack = 0;
00425     }
00426 
00427     return m_StatePacks->Get(m_NumberOfStatePacks-1, m_NumberOfStatesInLastPack++);
00428 }
00429 
00430 //fcs_state_ia_release
00431 void FCSFreecellData::StatePackRelease()
00432 {
00433     m_NumberOfStatesInLastPack--;
00434 }
00435 
00436 void FCSFreecellData::CheckStateBegin(FCSStateWithLocations** NewStateWithLocations, FCSStateWithLocations* StateWithLocations,
00437                                           FCSMoveStack *Move)
00438 {
00439     (*NewStateWithLocations) = StatePackAlloc();
00440     (*NewStateWithLocations)->Copy(StateWithLocations);
00441     (*NewStateWithLocations)->m_Parent = StateWithLocations;
00442     (*NewStateWithLocations)->m_MovesToParent = Move;
00443     // Make sure depth is consistent with the game graph.
00444     // I.e: the depth of every newly discovered state is derived from
00445     // the state from which it was discovered.
00446     (*NewStateWithLocations)->m_Depth = StateWithLocations->m_Depth + 1;
00447     (*NewStateWithLocations)->m_Visited = FCS_VISITED_NOT_VISITED; 
00448     Move->Reset();
00449 }
00450 
00451 bool FCSFreecellData::CheckStateEnd(FCSStateWithLocations** NewStateWithLocations, FCSStateWithLocations* StateWithLocations,
00452                                         FCSDerivedStatesList** DerivedStateList, FCSMoveStack** Move, FCSMove** TempMove, int depth, 
00453                                         FCSStateSolvingReturnCodes* ReturnCode)
00454 {
00455     FCSStateWithLocations* ExistingState;
00456     FCSStateSolvingReturnCodes Check;
00457 
00458 // The last move in a move stack should be FCS_MOVE_TYPE_CANONIZE
00459 // because it indicates that the order of the stacks and freecells
00460 // need to be recalculated 
00461 
00462     (*TempMove)->SetType(FCS_MOVE_TYPE_CANONIZE);
00463     (*Move)->Push(*TempMove);
00464 
00465     Check = CheckAndAddState(*NewStateWithLocations, &ExistingState, depth);
00466         
00467     if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00468         (Check == FCS_STATE_SUSPEND_PROCESS))
00469     {
00470         // This state is not going to be used, so
00471         // let's clean it.
00472         (*NewStateWithLocations)->CleanState();
00473         *ReturnCode = Check;
00474         return true;
00475     }
00476     else if (Check == FCS_STATE_ALREADY_EXISTS)
00477     {
00478         StatePackRelease();
00479         (*DerivedStateList)->AddState(ExistingState);
00480     }
00481     else
00482     {   
00483         (*DerivedStateList)->AddState(*NewStateWithLocations);
00484 
00485         // See above.
00486         (*Move) = CreateMoveStack();
00487     }
00488 
00489     return false;
00490 }
00491 
00492 FCSStateSolvingReturnCodes FCSFreecellData::CheckAndAddState(FCSStateWithLocations* NewState,
00493                                                                  FCSStateWithLocations** ExistingState,
00494                                                                  int Depth)
00495 {
00496     if (((m_MaxNumberOfCheckedStates >= 0) &&
00497         (m_NumberOfCheckedStates >= m_MaxNumberOfCheckedStates)) ||
00498         ((m_MaxNumberOfStatesInCollection >= 0) &&
00499         (m_NumberOfStatesInCollection >= m_MaxNumberOfStatesInCollection)))
00500     {
00501         return FCS_STATE_BEGIN_SUSPEND_PROCESS;
00502     }
00503 
00504     if ((m_MaxDepth >= 0) &&
00505         (m_MaxDepth <= Depth))
00506     {
00507         return FCS_STATE_EXCEEDS_MAX_DEPTH;
00508     }
00509 
00510     NewState->CanonizeState(m_NumberOfFreecells, m_NumberOfStacks);
00511     NewState->CacheStacks(m_StackStorage, m_NumberOfStacks);
00512 
00513     if (m_StateStorage->CheckAndInsert(ExistingState, NewState))
00514     {
00515         // The new state was not found in the cache, and it was already inserted
00516         m_NumberOfStatesInCollection++;
00517         return FCS_STATE_DOES_NOT_EXIST;
00518     }
00519 
00520     return FCS_STATE_ALREADY_EXISTS;
00521 }
00522 
00523 bool FCSFreecellData::IsParentCard(FCSCard* Child, FCSCard* Parent)
00524 {
00525     return ((Child->GetCardNumber()+1 == Parent->GetCardNumber()) && 
00526             ((m_SequencesAreBuiltBy == FCS_SEQ_BUILT_BY_RANK) ?
00527                 1 :
00528                 ((m_SequencesAreBuiltBy == FCS_SEQ_BUILT_BY_SUIT) ?
00529                    (Child->GetSuit() == Parent->GetSuit()) : 
00530                     ((Child->GetSuit() & 0x1) != (Parent->GetSuit()&0x1))
00531             ))
00532             );
00533 }
00534 
00535 int FCSFreecellData::CalculateMaxSequenceMoves(int FreecellNumber, int FreeStackNumber)
00536 {
00537     return ( m_IsUnlimitedSequenceMove ? INT_MAX :
00538               (
00539               (m_EmptyStacksFill == FCS_ES_FILLED_BY_ANY_CARD) ? 
00540                     ((FreecellNumber+1)<<(FreeStackNumber)) :
00541                     (FreecellNumber+1)
00542               )
00543            );
00544 }
00545 
00546 void FCSFreecellData::MoveSequence(FCSStateWithLocations* NewStateWithLocations, FCSCard* Card, FCSMoveStack *MoveStack, FCSMove** TempMove, 
00547                     int DestStack, int SourceStack, int Start, int End)
00548 {
00549     int Loop;
00550 
00551     for (Loop = Start; Loop <= End ; Loop++)
00552         NewStateWithLocations->PushStackCardIntoStack(DestStack, SourceStack, Loop);
00553 
00554     for (Loop = Start; Loop <= End ; Loop++)
00555         NewStateWithLocations->PopStackCard(SourceStack, Card);
00556 
00557     (*TempMove)->SetType(FCS_MOVE_TYPE_STACK_TO_STACK);
00558     (*TempMove)->SetSourceStack(SourceStack);
00559     (*TempMove)->SetDestStack(DestStack);
00560     (*TempMove)->SetNumberOfCardsInSequence(End-Start+1);
00561 
00562     MoveStack->Push(*TempMove);
00563 }

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