00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FCSSimpleSimonSolvingAlgorithm.h"
00010 #include "FCSAStarSolvingAlgorithm.h"
00011 #include "FCSBFSSolvingAlgorithm.h"
00012 #include "FCSDFSSolvingAlgorithm.h"
00013 #include "FCSRandomDFSSolvingAlgorithm.h"
00014 #include "FCSSoftDFSSolvingAlgorithm.h"
00015
00016
00017 FCSSimpleSimonSolvingAlgorithm::FCSSimpleSimonSolvingAlgorithm() : FCSFreecellData(), FCSFreecellAlgorithm()
00018 {
00019 }
00020
00021 FCSSimpleSimonSolvingAlgorithm::FCSSimpleSimonSolvingAlgorithm(FCCommandLineArguments* CommandLine) : FCSFreecellData(CommandLine), FCSFreecellAlgorithm()
00022 {
00023 }
00024
00025 FCSSimpleSimonSolvingAlgorithm::~FCSSimpleSimonSolvingAlgorithm()
00026 {
00027 }
00028
00029 FCSSimpleSimonSolvingAlgorithm* FCSSimpleSimonSolvingAlgorithm::Create(FCCommandLineArguments* CommandLine)
00030 {
00031
00032 if (CommandLine == NULL)
00033 return NULL;
00034
00035
00036 switch(CommandLine->GetSolvingMethodType())
00037 {
00038 case FCS_METHOD_HARD_DFS:
00039 return new FCSDFSSolvingAlgorithm<FCSSimpleSimonSolvingAlgorithm>(CommandLine);
00040 break;
00041 case FCS_METHOD_SOFT_DFS:
00042 return new FCSSoftDFSSolvingAlgorithm<FCSSimpleSimonSolvingAlgorithm>(CommandLine);
00043 break;
00044 case FCS_METHOD_BFS:
00045 return new FCSBFSSolvingAlgorithm<FCSSimpleSimonSolvingAlgorithm>(CommandLine);
00046 break;
00047 case FCS_METHOD_A_STAR:
00048 return new FCSAStarSolvingAlgorithm<FCSSimpleSimonSolvingAlgorithm>(CommandLine);
00049 break;
00050 case FCS_METHOD_RANDOM_DFS:
00051 return new FCSRandomDFSSolvingAlgorithm<FCSSimpleSimonSolvingAlgorithm>(CommandLine);
00052 break;
00053 default:
00054 return NULL;
00055 }
00056
00057 return NULL;
00058 }
00059
00060 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::RunTest(int TestNumber, FCSStateWithLocations* StateWithLocations,
00061 int Depth, int NumberOfFreeStacks,
00062 int NumberOfFreecells,
00063 FCSDerivedStatesList* DerivedStateList)
00064 {
00065 switch(TestNumber)
00066 {
00067 case 0:
00068 return MoveSequenceToFounds(StateWithLocations, Depth, NumberOfFreeStacks,
00069 NumberOfFreecells, DerivedStateList);
00070 case 1:
00071 return MoveSequenceToTrueParent(StateWithLocations, Depth, NumberOfFreeStacks,
00072 NumberOfFreecells, DerivedStateList);
00073 case 2:
00074 return MoveWholeStackSequenceToFalseParent(StateWithLocations, Depth, NumberOfFreeStacks,
00075 NumberOfFreecells, DerivedStateList);
00076 case 3:
00077 return MoveSequenceToTrueParentWithSomeCardsAbove(StateWithLocations, Depth, NumberOfFreeStacks,
00078 NumberOfFreecells, DerivedStateList);
00079 case 4:
00080 return MoveSequenceWithSomeCardsAboveToTrueParent(StateWithLocations, Depth, NumberOfFreeStacks,
00081 NumberOfFreecells, DerivedStateList);
00082 case 5:
00083 return MoveSequenceWithJunkSequenceAboveToTrueParentWithSomeCardsAbove(StateWithLocations, Depth,
00084 NumberOfFreeStacks, NumberOfFreecells, DerivedStateList);
00085 case 6:
00086 return MoveWholeStackSequenceToFalseParentWithSomeCardsAbove(StateWithLocations, Depth,
00087 NumberOfFreeStacks, NumberOfFreecells, DerivedStateList);
00088 case 7:
00089 return MoveSequenceToParentOnTheSameStack(StateWithLocations, Depth, NumberOfFreeStacks,
00090 NumberOfFreecells, DerivedStateList);
00091 case 8:
00092 return MoveSequenceToFalseParent(StateWithLocations, Depth, NumberOfFreeStacks,
00093 NumberOfFreecells, DerivedStateList);
00094 default:
00095 return FCS_STATE_IS_NOT_SOLVEABLE;
00096 }
00097 }
00098
00099 bool FCSSimpleSimonSolvingAlgorithm::IsSimpleSimonTrueParent(FCSCard* Parent, FCSCard* Child)
00100 {
00101 return (IsSimpleSimonFalseParent(Parent, Child) &&
00102 IsSimpleSimonTrueParentSuit(Parent, Child) );
00103 }
00104
00105 bool FCSSimpleSimonSolvingAlgorithm::IsSimpleSimonTrueParentSuit(FCSCard* Parent, FCSCard* Child)
00106 {
00107 return (Parent->GetSuit() == Child->GetSuit());
00108 }
00109
00110 bool FCSSimpleSimonSolvingAlgorithm::IsSimpleSimonFalseParent(FCSCard* Parent, FCSCard* Child)
00111 {
00112 return (Parent->GetCardNumber() == Child->GetCardNumber()+1);
00113 }
00114
00115 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceToFounds(FCSStateWithLocations* StateWithLocations,
00116 int Depth,
00117 int NumberOfFreeStacks,
00118 int NumberOfFreecells,
00119 FCSDerivedStatesList* DerivedStateList)
00120 {
00121 FCSStateWithLocations* NewStateWithLocations;
00122 FCSMoveStack* Moves = CreateMoveStack();
00123 FCSMove* TempMove = FCSMove::Create();
00124
00125 int NumberOfCardsInStack, HeightOfCard;
00126 FCSStateSolvingReturnCodes Check;
00127
00128 FCSCard *TempCard = FCSCard::Create(),
00129 *Card, *AboveCard;
00130
00131 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
00132 {
00133 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
00134 if (NumberOfCardsInStack < 13)
00135 continue;
00136
00137 Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
00138
00139
00140 for(HeightOfCard=2;HeightOfCard<=13;HeightOfCard++)
00141 {
00142 AboveCard = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-HeightOfCard);
00143 if (!IsSimpleSimonTrueParent(AboveCard, Card))
00144 break;
00145
00146 Card = AboveCard;
00147 }
00148
00149 if (HeightOfCard <= 13)
00150 continue;
00151
00152
00153 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00154
00155 for(HeightOfCard=0;HeightOfCard<13;HeightOfCard++)
00156 {
00157 NewStateWithLocations->PopStackCard(StackIndex, TempCard);
00158 NewStateWithLocations->IncrementFoundation(Card->GetSuit());
00159 }
00160
00161 TempMove->SetType(FCS_MOVE_TYPE_SEQ_TO_FOUNDATION);
00162 TempMove->SetSourceStack(StackIndex);
00163 TempMove->SetFoundation(Card->GetSuit());
00164 Moves->Push(TempMove);
00165
00166 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00167 &Moves, &TempMove, Depth, &Check))
00168 {
00169 delete TempCard;
00170 delete TempMove;
00171 return Check;
00172 }
00173 }
00174
00175 delete [] Moves;
00176 delete TempMove;
00177 delete TempCard;
00178
00179 return FCS_STATE_IS_NOT_SOLVEABLE;
00180 }
00181
00182 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceToTrueParent(FCSStateWithLocations* StateWithLocations,
00183 int Depth,
00184 int NumberOfFreeStacks,
00185 int NumberOfFreecells,
00186 FCSDerivedStatesList* DerivedStateList)
00187 {
00188
00189 FCSStateWithLocations* NewStateWithLocations;
00190 FCSMoveStack* Moves = CreateMoveStack();
00191 FCSMove* TempMove = FCSMove::Create();
00192
00193 int NumberOfCardsInStack, NumberOfTrueSequences, NumberOfCardsInDestStack;
00194 FCSStateSolvingReturnCodes Check;
00195
00196 FCSCard *TempCard = FCSCard::Create(),
00197 *Card, *NextCard;
00198
00199 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
00200 {
00201 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
00202 if (NumberOfCardsInStack <= 0)
00203 continue;
00204
00205
00206
00207 Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
00208 NumberOfTrueSequences = 1;
00209
00210 for(int HeightOfStack=NumberOfCardsInStack-2;HeightOfStack>=-1;HeightOfStack--)
00211 {
00212 for(int DestStack = 0;DestStack<m_NumberOfStacks;DestStack++)
00213 {
00214 if (DestStack == StackIndex)
00215 continue;
00216
00217 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
00218 if ((NumberOfCardsInDestStack > 0) &&
00219 (IsSimpleSimonTrueParent(StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1), Card)) &&
00220
00221
00222 (CalculateMaxSequenceMoves(0, NumberOfFreeStacks) >= NumberOfTrueSequences))
00223 {
00224
00225
00226 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00227
00228 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00229 DestStack, StackIndex, HeightOfStack+1, NumberOfCardsInStack-1);
00230
00231 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00232 &Moves, &TempMove, Depth, &Check))
00233 {
00234 delete TempCard;
00235 delete TempMove;
00236 return Check;
00237 }
00238 }
00239 }
00240
00241
00242
00243 if (HeightOfStack == -1)
00244 break;
00245
00246 NextCard = StateWithLocations->GetStackCard(StackIndex, HeightOfStack);
00247
00248 if (!IsSimpleSimonFalseParent(NextCard, Card))
00249 break;
00250
00251 if (!IsSimpleSimonTrueParentSuit(NextCard, Card))
00252 NumberOfTrueSequences++;
00253
00254 Card = NextCard;
00255 }
00256 }
00257
00258 delete [] Moves;
00259 delete TempMove;
00260 delete TempCard;
00261
00262 return FCS_STATE_IS_NOT_SOLVEABLE;
00263 }
00264
00265 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveWholeStackSequenceToFalseParent(FCSStateWithLocations* StateWithLocations,
00266 int Depth,
00267 int NumberOfFreeStacks,
00268 int NumberOfFreecells,
00269 FCSDerivedStatesList* DerivedStateList)
00270 {
00271 FCSStateWithLocations* NewStateWithLocations;
00272 FCSMoveStack* Moves = CreateMoveStack();
00273 FCSMove* TempMove = FCSMove::Create();
00274
00275 int NumberOfCardsInStack, HeightOfStack,
00276 NumberOfTrueSequences, NumberOfCardsInDestStack;
00277 FCSStateSolvingReturnCodes Check;
00278
00279 FCSCard *TempCard = FCSCard::Create(),
00280 *Card, *NextCard;
00281
00282 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
00283 {
00284 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
00285 if (NumberOfCardsInStack <= 0)
00286 continue;
00287
00288 Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
00289 NumberOfTrueSequences = 1;
00290
00291
00292 for(HeightOfStack=NumberOfCardsInStack-2;HeightOfStack>-1;HeightOfStack--)
00293 {
00294 NextCard = StateWithLocations->GetStackCard(StackIndex, HeightOfStack);
00295
00296 if (!IsSimpleSimonFalseParent(NextCard, Card))
00297 break;
00298
00299 if (!IsSimpleSimonTrueParentSuit(NextCard, Card))
00300 NumberOfTrueSequences++;
00301
00302 Card = NextCard;
00303 }
00304
00305
00306 if (HeightOfStack != -1)
00307 continue;
00308
00309 for(int DestStack=0;DestStack<m_NumberOfStacks;DestStack++)
00310 {
00311 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
00312
00313 if (NumberOfCardsInDestStack <= 0)
00314 continue;
00315
00316 if (!IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1), Card))
00317 continue;
00318
00319
00320
00321 if (CalculateMaxSequenceMoves(0, NumberOfFreeStacks) < NumberOfTrueSequences)
00322 continue;
00323
00324
00325 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00326
00327 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00328 DestStack, StackIndex, HeightOfStack+1, NumberOfCardsInStack-1);
00329
00330 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00331 &Moves, &TempMove, Depth, &Check))
00332 {
00333 delete TempCard;
00334 delete TempMove;
00335 return Check;
00336 }
00337 }
00338 }
00339
00340 delete [] Moves;
00341 delete TempMove;
00342 delete TempCard;
00343
00344 return FCS_STATE_IS_NOT_SOLVEABLE;
00345 }
00346
00347 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceToTrueParentWithSomeCardsAbove(FCSStateWithLocations* StateWithLocations,
00348 int Depth,
00349 int NumberOfFreeStacks,
00350 int NumberOfFreecells,
00351 FCSDerivedStatesList* DerivedStateList)
00352 {
00353 FCSStateWithLocations* NewStateWithLocations;
00354 FCSMoveStack* Moves = CreateMoveStack();
00355 FCSMove* TempMove = FCSMove::Create();
00356
00357 FCSStateSolvingReturnCodes Check;
00358
00359 int NumberOfCardsInStack, NumberOfTrueSequences, NumberOfCardsInDestStack,
00360 NumberOfSeparateFalseSequences, FalseSequencesIndex,
00361 AfterJunkNumberOfFreeStacks;
00362
00363 int AboveNumberOfTrueSequences[MAX_NUM_CARDS_IN_A_STACK],
00364 SeparatePointOfFalseSequences[MAX_NUM_CARDS_IN_A_STACK],
00365 StacksMap[MAX_NUM_STACKS],
00366 JunkMoveToStacks[MAX_NUM_STACKS];
00367
00368 FCSCard *TempCard = FCSCard::Create(),
00369 *Card, *NextCard;
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
00400 {
00401 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
00402 if (NumberOfCardsInStack <= 0)
00403 continue;
00404
00405 Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
00406 NumberOfTrueSequences = 1;
00407
00408 for(int HeightOfStack = NumberOfCardsInStack-2;HeightOfStack>=-1;HeightOfStack--)
00409 {
00410 for(int DestStack=0;DestStack<m_NumberOfStacks;DestStack++)
00411 {
00412 if (DestStack == StackIndex)
00413 continue;
00414
00415 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
00416 if (NumberOfCardsInDestStack <= 0)
00417 continue;
00418
00419 for(int DestStackCardIndex=NumberOfCardsInDestStack-1;DestStackCardIndex>=0;DestStackCardIndex--)
00420 {
00421 if (!IsSimpleSimonTrueParent(StateWithLocations->GetStackCard(DestStack, DestStackCardIndex), Card))
00422 continue;
00423
00424
00425 int AboveCardHeight;
00426 FCSCard *AboveCard, *UpAboveCard;
00427
00428 NumberOfSeparateFalseSequences = 0;
00429 AboveCard = StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1);
00430 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
00431 for(AboveCardHeight = NumberOfCardsInDestStack-2; AboveCardHeight > DestStackCardIndex; AboveCardHeight--)
00432 {
00433 UpAboveCard = StateWithLocations->GetStackCard(DestStack, AboveCardHeight);
00434 if (!IsSimpleSimonFalseParent(UpAboveCard, AboveCard))
00435 {
00436 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
00437 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
00438 }
00439 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] += ! (UpAboveCard->GetSuit() == AboveCard->GetSuit());
00440 AboveCard = UpAboveCard;
00441 }
00442
00443 if (DestStackCardIndex < NumberOfCardsInDestStack - 1)
00444 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
00445
00446 for(int a=0;a<m_NumberOfStacks;a++)
00447 StacksMap[a] = 0;
00448
00449 StacksMap[StackIndex] = 1;
00450 StacksMap[DestStack] = 1;
00451
00452 AfterJunkNumberOfFreeStacks = NumberOfFreeStacks;
00453
00454 for(FalseSequencesIndex=0;FalseSequencesIndex<NumberOfSeparateFalseSequences;FalseSequencesIndex++)
00455 {
00456
00457
00458
00459 int ClearJunkDestStack;
00460
00461
00462 for(ClearJunkDestStack=0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
00463 {
00464 int ClearJunkStackLength = StateWithLocations->GetStackLength(ClearJunkDestStack);
00465
00466 if ( (ClearJunkStackLength > 0) && (StacksMap[ClearJunkDestStack] == 0) &&
00467 (IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(ClearJunkDestStack, ClearJunkStackLength-1), StateWithLocations->GetStackCard(DestStack, SeparatePointOfFalseSequences[FalseSequencesIndex]))) &&
00468 (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) >= AboveNumberOfTrueSequences[FalseSequencesIndex]) )
00469 {
00470 StacksMap[ClearJunkDestStack] = 1;
00471 break;
00472 }
00473 }
00474
00475 if (ClearJunkDestStack == m_NumberOfStacks)
00476 {
00477 ClearJunkDestStack = -1;
00478
00479 if (NumberOfFreeStacks > 0)
00480 {
00481 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks-1) >= AboveNumberOfTrueSequences[FalseSequencesIndex])
00482 {
00483
00484 for(ClearJunkDestStack = 0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
00485 {
00486 if ((StateWithLocations->GetStackLength(ClearJunkDestStack) == 0) &&
00487 (StacksMap[ClearJunkDestStack] == 0))
00488 {
00489 StacksMap[ClearJunkDestStack] = 1;
00490 break;
00491 }
00492 }
00493 }
00494 AfterJunkNumberOfFreeStacks--;
00495 }
00496
00497 if (ClearJunkDestStack == -1)
00498 break;
00499 }
00500
00501 JunkMoveToStacks[FalseSequencesIndex] = ClearJunkDestStack;
00502 }
00503
00504 if (FalseSequencesIndex != NumberOfSeparateFalseSequences)
00505 continue;
00506
00507 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) < NumberOfTrueSequences)
00508 continue;
00509
00510
00511
00512
00513
00514
00515 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00516
00517
00518
00519 for(FalseSequencesIndex=0; FalseSequencesIndex<NumberOfSeparateFalseSequences; FalseSequencesIndex++)
00520 {
00521
00522 int End = ((FalseSequencesIndex == 0) ? (NumberOfCardsInDestStack-1) : (SeparatePointOfFalseSequences[FalseSequencesIndex-1]-1));
00523
00524 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00525 JunkMoveToStacks[FalseSequencesIndex], DestStack, SeparatePointOfFalseSequences[FalseSequencesIndex], End);
00526 }
00527
00528
00529 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00530 DestStack, StackIndex, HeightOfStack+1, NumberOfCardsInStack-1);
00531
00532 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00533 &Moves, &TempMove, Depth, &Check))
00534 {
00535 delete TempCard;
00536 delete TempMove;
00537 return Check;
00538 }
00539 }
00540 }
00541
00542
00543
00544 if (HeightOfStack == -1)
00545 break;
00546
00547
00548 if (!IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(StackIndex, HeightOfStack), Card))
00549 break;
00550
00551 NextCard = StateWithLocations->GetStackCard(StackIndex, HeightOfStack);
00552 if (!IsSimpleSimonTrueParentSuit(NextCard, Card))
00553 NumberOfTrueSequences++;
00554
00555 Card = NextCard;
00556 }
00557 }
00558
00559 delete [] Moves;
00560 delete TempMove;
00561 delete TempCard;
00562
00563 return FCS_STATE_IS_NOT_SOLVEABLE;
00564 }
00565
00566 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceWithSomeCardsAboveToTrueParent(FCSStateWithLocations* StateWithLocations,
00567 int Depth,
00568 int NumberOfFreeStacks,
00569 int NumberOfFreecells,
00570 FCSDerivedStatesList* DerivedStateList)
00571 {
00572 FCSStateWithLocations* NewStateWithLocations;
00573 FCSMoveStack* Moves = CreateMoveStack();
00574 FCSMove* TempMove = FCSMove::Create();
00575
00576 FCSStateSolvingReturnCodes Check;
00577
00578 int NumberOfCardsInStack, NumberOfTrueSequences, NumberOfCardsInDestStack,
00579 NumberOfSeparateFalseSequences, FalseSequencesIndex,
00580 AfterJunkNumberOfFreeStacks;
00581
00582 int AboveNumberOfTrueSequences[MAX_NUM_CARDS_IN_A_STACK],
00583 SeparatePointOfFalseSequences[MAX_NUM_CARDS_IN_A_STACK],
00584 StacksMap[MAX_NUM_STACKS],
00585 JunkMoveToStacks[MAX_NUM_STACKS];
00586
00587 FCSCard *TempCard = FCSCard::Create(),
00588 *Card, *SavedCard;
00589
00590 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
00591 {
00592 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
00593 if (NumberOfCardsInStack <= 0)
00594 continue;
00595
00596 for(int StackCard = NumberOfCardsInStack-1 ; StackCard >= 0 ; StackCard-- )
00597 {
00598 int AboveCardHeight, EndOfSourceSequence;
00599 FCSCard *AboveCard, *UpAboveCard;
00600
00601 SavedCard = Card = StateWithLocations->GetStackCard(StackIndex, StackCard);
00602 NumberOfTrueSequences = 1;
00603
00604 for (EndOfSourceSequence = StackCard+1; EndOfSourceSequence < NumberOfCardsInStack ; EndOfSourceSequence++)
00605 {
00606 AboveCard = StateWithLocations->GetStackCard(StackIndex, EndOfSourceSequence);
00607 if (!IsSimpleSimonFalseParent(Card, AboveCard))
00608 break;
00609
00610 if (!IsSimpleSimonTrueParentSuit(Card, AboveCard))
00611 NumberOfTrueSequences++;
00612
00613 Card = AboveCard;
00614 }
00615
00616 if (EndOfSourceSequence == NumberOfCardsInStack)
00617 continue;
00618
00619
00620 NumberOfSeparateFalseSequences = 0;
00621 AboveCard = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
00622 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
00623 for(AboveCardHeight = NumberOfCardsInStack-2 ; AboveCardHeight > EndOfSourceSequence-1; AboveCardHeight--)
00624 {
00625 UpAboveCard = StateWithLocations->GetStackCard(StackIndex, AboveCardHeight);
00626 if (!IsSimpleSimonFalseParent(UpAboveCard, AboveCard))
00627 {
00628 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
00629 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
00630 }
00631 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] += ! (UpAboveCard->GetSuit() == AboveCard->GetSuit());
00632 AboveCard = UpAboveCard;
00633 }
00634
00635 if (EndOfSourceSequence-1 < NumberOfCardsInStack-1)
00636 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
00637
00638 for(int DestStack=0;DestStack<m_NumberOfStacks;DestStack++)
00639 {
00640 if (DestStack == StackIndex)
00641 continue;
00642
00643 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
00644
00645 if (NumberOfCardsInDestStack <= 0)
00646 continue;
00647
00648 if (!IsSimpleSimonTrueParent(StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1), SavedCard))
00649 continue;
00650
00651
00652
00653
00654 for(int a=0;a<m_NumberOfStacks;a++)
00655 StacksMap[a] = 0;
00656
00657 StacksMap[StackIndex] = 1;
00658 StacksMap[DestStack] = 1;
00659
00660 AfterJunkNumberOfFreeStacks = NumberOfFreeStacks;
00661
00662 for(FalseSequencesIndex=0;FalseSequencesIndex<NumberOfSeparateFalseSequences;FalseSequencesIndex++)
00663 {
00664
00665 int ClearJunkDestStack;
00666
00667
00668 for(ClearJunkDestStack=0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
00669 {
00670 int ClearJunkStackLength = StateWithLocations->GetStackLength(ClearJunkDestStack);
00671
00672 if ((ClearJunkStackLength > 0) && (StacksMap[ClearJunkDestStack] == 0) &&
00673 (IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(ClearJunkDestStack, ClearJunkStackLength-1), StateWithLocations->GetStackCard(StackIndex, SeparatePointOfFalseSequences[FalseSequencesIndex]))) &&
00674 (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) >= AboveNumberOfTrueSequences[FalseSequencesIndex]))
00675 {
00676 StacksMap[ClearJunkDestStack] = 1;
00677 break;
00678 }
00679 }
00680
00681 if (ClearJunkDestStack == m_NumberOfStacks)
00682 {
00683 ClearJunkDestStack = -1;
00684
00685
00686 if (NumberOfFreeStacks > 0)
00687 {
00688 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks-1) >= AboveNumberOfTrueSequences[FalseSequencesIndex])
00689 {
00690
00691 for(ClearJunkDestStack = 0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
00692 {
00693 if ((StateWithLocations->GetStackLength(ClearJunkDestStack) == 0) && (StacksMap[ClearJunkDestStack] == 0))
00694 {
00695 StacksMap[ClearJunkDestStack] = 1;
00696 break;
00697 }
00698 }
00699 }
00700 AfterJunkNumberOfFreeStacks--;
00701 }
00702
00703 if (ClearJunkDestStack == -1)
00704 break;
00705 }
00706
00707 JunkMoveToStacks[FalseSequencesIndex] = ClearJunkDestStack;
00708 }
00709
00710 if (FalseSequencesIndex != NumberOfSeparateFalseSequences)
00711 continue;
00712
00713 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) <= NumberOfTrueSequences)
00714 continue;
00715
00716 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00717
00718
00719
00720 for(FalseSequencesIndex=0; FalseSequencesIndex<NumberOfSeparateFalseSequences; FalseSequencesIndex++)
00721 {
00722 int End = ((FalseSequencesIndex == 0) ? (NumberOfCardsInStack-1) : (SeparatePointOfFalseSequences[FalseSequencesIndex-1]-1));
00723
00724 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00725 JunkMoveToStacks[FalseSequencesIndex], StackIndex, SeparatePointOfFalseSequences[FalseSequencesIndex], End);
00726 }
00727
00728 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00729 DestStack, StackIndex, StackCard, EndOfSourceSequence-1);
00730
00731 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00732 &Moves, &TempMove, Depth, &Check))
00733 {
00734 delete TempMove;
00735 delete TempCard;
00736 return Check;
00737 }
00738 }
00739 }
00740 }
00741
00742 delete [] Moves;
00743 delete TempMove;
00744 delete TempCard;
00745
00746 return FCS_STATE_IS_NOT_SOLVEABLE;
00747 }
00748
00749 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceWithJunkSequenceAboveToTrueParentWithSomeCardsAbove(FCSStateWithLocations* StateWithLocations,
00750 int Depth,
00751 int NumberOfFreeStacks,
00752 int NumberOfFreecells,
00753 FCSDerivedStatesList* DerivedStateList)
00754 {
00755 FCSStateWithLocations* NewStateWithLocations;
00756 FCSMoveStack* Moves = CreateMoveStack();
00757 FCSMove* TempMove = FCSMove::Create();
00758
00759 FCSStateSolvingReturnCodes Check;
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 int NumberOfCardsInStack, HeightOfCardInStack,
00785 NumberOfTrueSequences, NumberOfCardsInDestStack,
00786 NumberOfSourceJunkTrueSequences, NumberOfSeparateFalseSequences,
00787 FalseSequencesIndex, AfterJunkNumberOfFreeStacks, EndOfJunk;
00788
00789 int AboveNumberOfTrueSequences[MAX_NUM_CARDS_IN_A_STACK],
00790 SeparatePointOfFalseSequences[MAX_NUM_CARDS_IN_A_STACK],
00791 StacksMap[MAX_NUM_STACKS],
00792 JunkMoveToStacks[MAX_NUM_STACKS];
00793
00794 FCSCard *TempCard = FCSCard::Create(),
00795 *Card, *SavedCard;
00796
00797 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
00798 {
00799 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
00800 if (NumberOfCardsInStack <= 0)
00801 continue;
00802
00803 SavedCard = Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
00804 NumberOfSourceJunkTrueSequences = 1;
00805
00806
00807 for(HeightOfCardInStack=NumberOfCardsInStack-2;HeightOfCardInStack>-1;HeightOfCardInStack--)
00808 {
00809 Card = StateWithLocations->GetStackCard(StackIndex, HeightOfCardInStack);
00810 if (!IsSimpleSimonFalseParent(Card, SavedCard))
00811 break;
00812
00813 if (!IsSimpleSimonTrueParentSuit(Card, SavedCard))
00814 NumberOfSourceJunkTrueSequences++;
00815
00816 SavedCard = Card;
00817 }
00818
00819 if (HeightOfCardInStack == -1)
00820 continue;
00821
00822 EndOfJunk = HeightOfCardInStack;
00823 NumberOfTrueSequences = 1;
00824
00825 for(;HeightOfCardInStack>-1;HeightOfCardInStack--)
00826 {
00827 Card = StateWithLocations->GetStackCard(StackIndex, HeightOfCardInStack);
00828 if (!IsSimpleSimonFalseParent(Card, SavedCard))
00829 break;
00830
00831 if (!IsSimpleSimonTrueParentSuit(Card, SavedCard))
00832 NumberOfTrueSequences++;
00833
00834 SavedCard = Card;
00835 }
00836
00837 SavedCard = Card;
00838
00839 for(int DestStack =0;DestStack<m_NumberOfStacks;DestStack++)
00840 {
00841 if (DestStack == StackIndex)
00842 continue;
00843
00844 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
00845
00846 if (NumberOfCardsInDestStack <= 1)
00847 continue;
00848
00849
00850
00851 for(int DestStackCardIndex=NumberOfCardsInDestStack-2;DestStackCardIndex>=0;DestStackCardIndex--)
00852 {
00853 if (!IsSimpleSimonTrueParent(StateWithLocations->GetStackCard(DestStack, DestStackCardIndex), SavedCard))
00854 continue;
00855
00856
00857 int AboveCardHeight;
00858 FCSCard *AboveCard, *UpAboveCard;
00859
00860 NumberOfSeparateFalseSequences = 0;
00861 AboveCard = StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1);
00862 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
00863 for(AboveCardHeight = NumberOfCardsInDestStack-2; AboveCardHeight > DestStackCardIndex; AboveCardHeight--)
00864 {
00865 UpAboveCard = StateWithLocations->GetStackCard(DestStack, AboveCardHeight);
00866 if (!IsSimpleSimonFalseParent(UpAboveCard, AboveCard))
00867 {
00868 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
00869 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
00870 }
00871 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] += ! (IsSimpleSimonTrueParentSuit(UpAboveCard, AboveCard));
00872 AboveCard = UpAboveCard;
00873 }
00874
00875 if (DestStackCardIndex < NumberOfCardsInDestStack - 1)
00876 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
00877
00878 for(int a=0;a<m_NumberOfStacks;a++)
00879 StacksMap[a] = 0;
00880
00881 StacksMap[StackIndex] = 1;
00882 StacksMap[DestStack] = 1;
00883
00884 AfterJunkNumberOfFreeStacks = NumberOfFreeStacks;
00885
00886 for(FalseSequencesIndex=0;FalseSequencesIndex<NumberOfSeparateFalseSequences+1;FalseSequencesIndex++)
00887 {
00888
00889 int ClearJunkDestStack;
00890
00891 FCSCard *TheCard = (FalseSequencesIndex == NumberOfSeparateFalseSequences) ?
00892 StateWithLocations->GetStackCard(StackIndex, EndOfJunk+1) :
00893 StateWithLocations->GetStackCard(DestStack, SeparatePointOfFalseSequences[FalseSequencesIndex]);
00894
00895 int TheNumberOfTrueSequences = (FalseSequencesIndex == NumberOfSeparateFalseSequences) ?
00896 NumberOfSourceJunkTrueSequences :
00897 AboveNumberOfTrueSequences[FalseSequencesIndex];
00898
00899
00900 for(ClearJunkDestStack=0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
00901 {
00902 int ClearJunkStackLength = StateWithLocations->GetStackLength(ClearJunkDestStack);
00903
00904 if ((ClearJunkStackLength > 0) && (StacksMap[ClearJunkDestStack] == 0) &&
00905 (IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(ClearJunkDestStack, ClearJunkStackLength-1), TheCard)) &&
00906 (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) >= TheNumberOfTrueSequences))
00907 {
00908 StacksMap[ClearJunkDestStack] = 1;
00909 break;
00910 }
00911 }
00912
00913 if (ClearJunkDestStack == m_NumberOfStacks)
00914 {
00915 ClearJunkDestStack = -1;
00916
00917
00918 if (NumberOfFreeStacks > 0)
00919 {
00920 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks-1) >= TheNumberOfTrueSequences)
00921 {
00922
00923 for(ClearJunkDestStack = 0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
00924 {
00925 if ((StateWithLocations->GetStackLength(ClearJunkDestStack) == 0) &&
00926 (StacksMap[ClearJunkDestStack] == 0))
00927 {
00928 StacksMap[ClearJunkDestStack] = 1;
00929 break;
00930 }
00931 }
00932 }
00933 AfterJunkNumberOfFreeStacks--;
00934 }
00935
00936 if (ClearJunkDestStack == -1)
00937 break;
00938 }
00939
00940 JunkMoveToStacks[FalseSequencesIndex] = ClearJunkDestStack;
00941 }
00942
00943 if (FalseSequencesIndex != NumberOfSeparateFalseSequences+1)
00944 continue;
00945
00946 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) < NumberOfTrueSequences)
00947 continue;
00948
00949
00950 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
00951
00952
00953
00954 for(FalseSequencesIndex=0; FalseSequencesIndex<NumberOfSeparateFalseSequences+1; FalseSequencesIndex++)
00955 {
00956 int Start, End, SourceStack;
00957
00958 if (FalseSequencesIndex == NumberOfSeparateFalseSequences)
00959 {
00960 Start = EndOfJunk+1;
00961 End = NumberOfCardsInStack-1;
00962 SourceStack = StackIndex;
00963 }
00964 else
00965 {
00966 Start = SeparatePointOfFalseSequences[FalseSequencesIndex];
00967 End = ((FalseSequencesIndex == 0) ? (NumberOfCardsInDestStack-1) : (SeparatePointOfFalseSequences[FalseSequencesIndex-1]-1));
00968 SourceStack = DestStack;
00969 }
00970
00971 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00972 JunkMoveToStacks[FalseSequencesIndex], SourceStack, Start, End);
00973 }
00974
00975
00976 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
00977 DestStack, StackIndex, HeightOfCardInStack, EndOfJunk);
00978
00979 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
00980 &Moves, &TempMove, Depth, &Check))
00981 {
00982 delete TempMove;
00983 delete TempCard;
00984 return Check;
00985 }
00986 }
00987 }
00988 }
00989
00990 delete [] Moves;
00991 delete TempMove;
00992 delete TempCard;
00993
00994 return FCS_STATE_IS_NOT_SOLVEABLE;
00995 }
00996
00997 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveWholeStackSequenceToFalseParentWithSomeCardsAbove(FCSStateWithLocations* StateWithLocations,
00998 int Depth,
00999 int NumberOfFreeStacks,
01000 int NumberOfFreecells,
01001 FCSDerivedStatesList* DerivedStateList)
01002 {
01003 FCSStateWithLocations* NewStateWithLocations;
01004 FCSMoveStack* Moves = CreateMoveStack();
01005 FCSMove* TempMove = FCSMove::Create();
01006
01007 FCSStateSolvingReturnCodes Check;
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 int NumberOfCardsInStack, HeightOfCardInStack,
01036 NumberOfTrueSequences, NumberOfCardsInDestStack,
01037 NumberOfSeparateFalseSequences, FalseSequencesIndex, AfterJunkNumberOfFreeStacks;
01038
01039 int AboveNumberOfTrueSequences[MAX_NUM_CARDS_IN_A_STACK],
01040 SeparatePointOfFalseSequences[MAX_NUM_CARDS_IN_A_STACK],
01041 StacksMap[MAX_NUM_STACKS],
01042 JunkMoveToStacks[MAX_NUM_STACKS];
01043
01044 FCSCard *TempCard = FCSCard::Create(),
01045 *Card, *SavedCard;
01046
01047 for(int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
01048 {
01049 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
01050 if (NumberOfCardsInStack <= 0)
01051 continue;
01052
01053 SavedCard = Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
01054 NumberOfTrueSequences = 1;
01055
01056 for(HeightOfCardInStack=NumberOfCardsInStack-2;HeightOfCardInStack>-1;HeightOfCardInStack--)
01057 {
01058 Card = StateWithLocations->GetStackCard(StackIndex, HeightOfCardInStack);
01059 if (!IsSimpleSimonFalseParent(Card, SavedCard))
01060 break;
01061
01062 if (!IsSimpleSimonTrueParentSuit(Card, SavedCard))
01063 NumberOfTrueSequences++;
01064
01065 SavedCard = Card;
01066 }
01067
01068 if (HeightOfCardInStack != -1)
01069 continue;
01070
01071 for(int DestStack=0;DestStack<m_NumberOfStacks;DestStack++)
01072 {
01073 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
01074 if (NumberOfCardsInDestStack <= 0)
01075 continue;
01076
01077 for(int DestStackCardIndex=NumberOfCardsInDestStack-1;DestStackCardIndex>=0;DestStackCardIndex--)
01078 {
01079 if (!IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(DestStack, DestStackCardIndex), SavedCard))
01080 continue;
01081
01082
01083 int AboveCardHeight;
01084 FCSCard *AboveCard, *UpAboveCard;
01085
01086 NumberOfSeparateFalseSequences = 0;
01087 AboveCard = StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1);
01088 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
01089 for(AboveCardHeight = NumberOfCardsInDestStack-2 ; AboveCardHeight > DestStackCardIndex; AboveCardHeight--)
01090 {
01091 UpAboveCard = StateWithLocations->GetStackCard(DestStack, AboveCardHeight);
01092 if (!IsSimpleSimonFalseParent(UpAboveCard, AboveCard))
01093 {
01094 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
01095 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
01096 }
01097 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] += ! (IsSimpleSimonTrueParentSuit(UpAboveCard, AboveCard));
01098 AboveCard = UpAboveCard;
01099 }
01100
01101 if (DestStackCardIndex < NumberOfCardsInDestStack - 1)
01102 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
01103
01104 for(int a=0;a<m_NumberOfStacks;a++)
01105 StacksMap[a] = 0;
01106
01107 StacksMap[StackIndex] = 1;
01108 StacksMap[DestStack] = 1;
01109
01110 AfterJunkNumberOfFreeStacks = NumberOfFreeStacks;
01111
01112 for(FalseSequencesIndex=0;FalseSequencesIndex<NumberOfSeparateFalseSequences;FalseSequencesIndex++)
01113 {
01114
01115 int ClearJunkDestStack,
01116 TheNumberOfTrueSequences = AboveNumberOfTrueSequences[FalseSequencesIndex];
01117
01118
01119 for(ClearJunkDestStack=0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
01120 {
01121 int ClearJunkStackLength = StateWithLocations->GetStackLength(ClearJunkDestStack);
01122
01123 if ((ClearJunkStackLength > 0) && (StacksMap[ClearJunkDestStack] == 0) &&
01124 (IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(ClearJunkDestStack, ClearJunkStackLength-1),
01125 StateWithLocations->GetStackCard(DestStack, SeparatePointOfFalseSequences[FalseSequencesIndex]))) &&
01126 (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreeStacks) >= TheNumberOfTrueSequences))
01127 {
01128 StacksMap[ClearJunkDestStack] = 1;
01129 break;
01130 }
01131 }
01132
01133 if (ClearJunkDestStack == m_NumberOfStacks)
01134 break;
01135
01136 JunkMoveToStacks[FalseSequencesIndex] = ClearJunkDestStack;
01137 }
01138
01139 if (FalseSequencesIndex != NumberOfSeparateFalseSequences)
01140 continue;
01141
01142
01143
01144 if (CalculateMaxSequenceMoves(0, NumberOfFreeStacks) < NumberOfTrueSequences)
01145 continue;
01146
01147
01148 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
01149
01150
01151 for(FalseSequencesIndex=0; FalseSequencesIndex<NumberOfSeparateFalseSequences; FalseSequencesIndex++)
01152 {
01153 int End = ((FalseSequencesIndex == 0) ? (NumberOfCardsInDestStack-1) : (SeparatePointOfFalseSequences[FalseSequencesIndex-1]-1));
01154
01155 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
01156 JunkMoveToStacks[FalseSequencesIndex], DestStack, SeparatePointOfFalseSequences[FalseSequencesIndex], End);
01157 }
01158
01159
01160 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
01161 DestStack, StackIndex, HeightOfCardInStack+1, NumberOfCardsInStack-1);
01162
01163 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
01164 &Moves, &TempMove, Depth, &Check))
01165 {
01166 delete TempMove;
01167 delete TempCard;
01168 return Check;
01169 }
01170 }
01171 }
01172 }
01173
01174 delete [] Moves;
01175 delete TempMove;
01176 delete TempCard;
01177
01178 return FCS_STATE_IS_NOT_SOLVEABLE;
01179
01180 }
01181
01182 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceToParentOnTheSameStack(FCSStateWithLocations* StateWithLocations,
01183 int Depth,
01184 int NumberOfFreeStacks,
01185 int NumberOfFreecells,
01186 FCSDerivedStatesList* DerivedStateList)
01187 {
01188 FCSStateWithLocations* NewStateWithLocations;
01189 FCSMoveStack* Moves = CreateMoveStack();
01190 FCSMove* TempMove = FCSMove::Create();
01191
01192 FCSStateSolvingReturnCodes Check;
01193
01194 FCSCard *ParentCard, *ChildCard,
01195 *TempCard = FCSCard::Create();
01196 int NumberOfCardsInStack,
01197 AfterJunkNumberOfFreestacks,
01198 FalseSequencesIndex,
01199 ChildSequencesIndex;
01200
01201 for(int StackIndex=0 ; StackIndex < m_NumberOfStacks ; StackIndex++)
01202 {
01203 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
01204 if (NumberOfCardsInStack <= 2)
01205 continue;
01206
01207
01208 for(int ParentCardIndex=0; ParentCardIndex < NumberOfCardsInStack-1 ; ParentCardIndex++)
01209 {
01210 ParentCard = StateWithLocations->GetStackCard(StackIndex, ParentCardIndex);
01211 if (IsSimpleSimonTrueParent(ParentCard, StateWithLocations->GetStackCard(StackIndex, ParentCardIndex+1)))
01212 continue;
01213
01214 for(int ChildCardIndex = ParentCardIndex + 2 ; ChildCardIndex < NumberOfCardsInStack ; ChildCardIndex++)
01215 {
01216 ChildCard = StateWithLocations->GetStackCard(StackIndex, ChildCardIndex);
01217 if (!IsSimpleSimonTrueParent(ParentCard, ChildCard))
01218 continue;
01219
01220
01221
01222 int AboveNumberOfTrueSequences[MAX_NUM_CARDS_IN_A_STACK],
01223 SeparatePointOfFalseSequences[MAX_NUM_CARDS_IN_A_STACK],
01224 StacksMap[MAX_NUM_STACKS],
01225 JunkMoveToStacks[MAX_NUM_STACKS];
01226
01227 FCSCard *AboveCard, *UpAboveCard;
01228 int NumberOfSeparateFalseSequences,
01229 AboveCardHeight,
01230 EndOfChildSequence = ChildCardIndex,
01231 ChildNumberOfTrueSequences = 1;
01232
01233 while ((EndOfChildSequence+1 < NumberOfCardsInStack) &&
01234 (IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(StackIndex, EndOfChildSequence),
01235 StateWithLocations->GetStackCard(StackIndex, EndOfChildSequence+1))))
01236 {
01237 ChildNumberOfTrueSequences += (!IsSimpleSimonTrueParent(
01238 StateWithLocations->GetStackCard(StackIndex, EndOfChildSequence),
01239 StateWithLocations->GetStackCard(StackIndex, EndOfChildSequence+1)));
01240 EndOfChildSequence++;
01241 }
01242
01243 NumberOfSeparateFalseSequences = 0;
01244 AboveCard = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
01245 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
01246 for(AboveCardHeight = NumberOfCardsInStack-2; AboveCardHeight > EndOfChildSequence ; AboveCardHeight--)
01247 {
01248 UpAboveCard = StateWithLocations->GetStackCard(StackIndex, AboveCardHeight);
01249 if (!IsSimpleSimonFalseParent(UpAboveCard, AboveCard))
01250 {
01251
01252 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
01253 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
01254 }
01255 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] += ! (IsSimpleSimonTrueParentSuit(UpAboveCard, AboveCard));
01256 AboveCard = UpAboveCard;
01257 }
01258
01259 if (EndOfChildSequence < NumberOfCardsInStack - 1)
01260 {
01261 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
01262 }
01263
01264
01265 ChildSequencesIndex = NumberOfSeparateFalseSequences;
01266 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = ChildNumberOfTrueSequences;
01267 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = ChildCardIndex;
01268
01269
01270 AboveCard = StateWithLocations->GetStackCard(StackIndex, ChildCardIndex-1);
01271 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
01272 for(AboveCardHeight = ChildCardIndex-2; AboveCardHeight > ParentCardIndex ; AboveCardHeight--)
01273 {
01274 UpAboveCard = StateWithLocations->GetStackCard(StackIndex, AboveCardHeight);
01275 if (!IsSimpleSimonFalseParent(UpAboveCard, AboveCard))
01276 {
01277 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
01278 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] = 1;
01279 }
01280 AboveNumberOfTrueSequences[NumberOfSeparateFalseSequences] += ! (IsSimpleSimonTrueParentSuit(UpAboveCard, AboveCard));
01281 AboveCard = UpAboveCard;
01282 }
01283
01284 if (ParentCardIndex < ChildCardIndex - 1)
01285 SeparatePointOfFalseSequences[NumberOfSeparateFalseSequences++] = AboveCardHeight+1;
01286
01287 for(int a = 0 ; a < m_NumberOfStacks ; a++)
01288 StacksMap[a] = 0;
01289
01290 StacksMap[StackIndex] = 1;
01291
01292 AfterJunkNumberOfFreestacks = NumberOfFreeStacks;
01293
01294 for(FalseSequencesIndex=0;FalseSequencesIndex<NumberOfSeparateFalseSequences;FalseSequencesIndex++)
01295 {
01296
01297 int ClearJunkDestStack;
01298
01299
01300 for(ClearJunkDestStack=0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
01301 {
01302 int ClearJunkStackLength = StateWithLocations->GetStackLength(ClearJunkDestStack);
01303
01304 if ((ClearJunkStackLength > 0) && (StacksMap[ClearJunkDestStack] == 0) &&
01305 (IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(ClearJunkDestStack, ClearJunkStackLength-1), StateWithLocations->GetStackCard(StackIndex, SeparatePointOfFalseSequences[FalseSequencesIndex]))) &&
01306 (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreestacks) >= AboveNumberOfTrueSequences[FalseSequencesIndex]))
01307 {
01308 StacksMap[ClearJunkDestStack] = 1;
01309 break;
01310 }
01311 }
01312
01313 if (ClearJunkDestStack == m_NumberOfStacks)
01314 {
01315 ClearJunkDestStack = -1;
01316
01317
01318 if (NumberOfFreeStacks > 0)
01319 {
01320 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreestacks-1) >= AboveNumberOfTrueSequences[FalseSequencesIndex])
01321 {
01322
01323 for(ClearJunkDestStack = 0; ClearJunkDestStack < m_NumberOfStacks; ClearJunkDestStack++)
01324 {
01325 if ((StateWithLocations->GetStackLength(ClearJunkDestStack) == 0) &&
01326 (StacksMap[ClearJunkDestStack] == 0))
01327 {
01328 StacksMap[ClearJunkDestStack] = 1;
01329 break;
01330 }
01331 }
01332 }
01333 AfterJunkNumberOfFreestacks--;
01334 }
01335
01336 if (ClearJunkDestStack == -1)
01337 break;
01338 }
01339
01340 JunkMoveToStacks[FalseSequencesIndex] = ClearJunkDestStack;
01341 }
01342
01343 if (FalseSequencesIndex != NumberOfSeparateFalseSequences)
01344 continue;
01345
01346
01347 if (CalculateMaxSequenceMoves(0, AfterJunkNumberOfFreestacks) < ChildNumberOfTrueSequences)
01348 continue;
01349
01350
01351 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
01352
01353
01354 for(FalseSequencesIndex=0; FalseSequencesIndex<NumberOfSeparateFalseSequences; FalseSequencesIndex++)
01355 {
01356 int End = ((FalseSequencesIndex == 0) ? (NumberOfCardsInStack-1) : (SeparatePointOfFalseSequences[FalseSequencesIndex-1]-1));
01357
01358 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
01359 JunkMoveToStacks[FalseSequencesIndex], StackIndex, SeparatePointOfFalseSequences[FalseSequencesIndex], End);
01360 }
01361
01362 int End2 = NewStateWithLocations->GetStackLength(JunkMoveToStacks[ChildSequencesIndex])-1;
01363 int Start = End2 - (EndOfChildSequence - ChildCardIndex);
01364
01365 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
01366 StackIndex, JunkMoveToStacks[ChildSequencesIndex], Start, End2);
01367
01368 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
01369 &Moves, &TempMove, Depth, &Check))
01370 {
01371 delete TempMove;
01372 delete TempCard;
01373 return Check;
01374 }
01375 }
01376 }
01377 }
01378
01379 delete [] Moves;
01380 delete TempMove;
01381 delete TempCard;
01382
01383 return FCS_STATE_IS_NOT_SOLVEABLE;
01384 }
01385
01386 FCSStateSolvingReturnCodes FCSSimpleSimonSolvingAlgorithm::MoveSequenceToFalseParent(FCSStateWithLocations* StateWithLocations,
01387 int Depth,
01388 int NumberOfFreeStacks,
01389 int NumberOfFreecells,
01390 FCSDerivedStatesList* DerivedStateList)
01391 {
01392 FCSStateWithLocations* NewStateWithLocations;
01393 FCSMoveStack* Moves = CreateMoveStack();
01394 FCSMove* TempMove = FCSMove::Create();
01395 FCSStateSolvingReturnCodes Check;
01396
01397 FCSCard *TempCard = FCSCard::Create(),
01398 *Card, *NextCard;
01399 int NumberOfCardsInStack, SequenceSize,
01400 NumberOfTrueSequences, HeightOfStack,
01401 NumberOfCardsInDestStack;
01402
01403
01404 for (int StackIndex=0;StackIndex<m_NumberOfStacks;StackIndex++)
01405 {
01406 NumberOfCardsInStack = StateWithLocations->GetStackLength(StackIndex);
01407 if (NumberOfCardsInStack <= 0)
01408 continue;
01409
01410 Card = StateWithLocations->GetStackCard(StackIndex, NumberOfCardsInStack-1);
01411 NumberOfTrueSequences = 1;
01412 SequenceSize = 1;
01413
01414 for (HeightOfStack=NumberOfCardsInStack-2;HeightOfStack>-1;HeightOfStack--)
01415 {
01416 NextCard = StateWithLocations->GetStackCard(StackIndex, HeightOfStack);
01417
01418 if (!IsSimpleSimonFalseParent(NextCard, Card))
01419 break;
01420
01421 SequenceSize++;
01422
01423 if (!IsSimpleSimonTrueParentSuit(NextCard, Card))
01424 NumberOfTrueSequences++;
01425
01426 Card = NextCard;
01427 }
01428
01429
01430
01431
01432
01433
01434 for (int DestStack=0;DestStack<m_NumberOfStacks;DestStack++)
01435 {
01436 if (DestStack == StackIndex)
01437 continue;
01438
01439 NumberOfCardsInDestStack = StateWithLocations->GetStackLength(DestStack);
01440 if (NumberOfCardsInDestStack <= 0)
01441 continue;
01442
01443 if (!IsSimpleSimonFalseParent(StateWithLocations->GetStackCard(DestStack, NumberOfCardsInDestStack-1), Card))
01444 continue;
01445
01446
01447
01448 if (CalculateMaxSequenceMoves(0, NumberOfFreeStacks) < NumberOfTrueSequences)
01449 continue;
01450
01451
01452 CheckStateBegin(&NewStateWithLocations, StateWithLocations, Moves);
01453
01454 MoveSequence(NewStateWithLocations, TempCard, Moves, &TempMove,
01455 DestStack, StackIndex, HeightOfStack+1, HeightOfStack+SequenceSize);
01456
01457 if (CheckStateEnd(&NewStateWithLocations, StateWithLocations, &DerivedStateList,
01458 &Moves, &TempMove, Depth, &Check))
01459 {
01460 delete TempCard;
01461 delete TempMove;
01462 return Check;
01463 }
01464 }
01465 }
01466
01467 delete [] Moves;
01468 delete TempCard;
01469 delete TempMove;
01470
01471 return FCS_STATE_IS_NOT_SOLVEABLE;
01472 }