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

FCCommandLineArguments.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <stdio.h>
00012 #include <iostream.h>
00013 #include "FCCommandLineArguments.h"
00014 #include "FCPresets.h"
00015 #include "Config.h"
00016 
00018 void DisplayHelp();
00019 
00020 FCCommandLineArguments::FCCommandLineArguments()
00021 {
00022     m_DisplayHelp = false;
00023     m_DebugDisplayInfo = new FCSDebugDisplayInfo();
00024 
00025     m_DebugDisplayInfo->m_NumberOfFreecells = m_NumberOfFreecells = DEFAULT_NUMBER_OF_FREECELLS;
00026     m_DebugDisplayInfo->m_NumberOfStacks = m_NumberOfStacks = DEFAULT_NUMBER_OF_STACKS;
00027     m_DebugDisplayInfo->m_NumberOfDecks = m_NumberOfDecks = DEFAULT_NUMBER_OF_DECKS;
00028     m_SequencesBuiltBy[0] = NULL;
00029     m_SequencesBuiltByType = DEFAULT_BUILD_SEQUENCE_TYPE;
00030     m_SequenceMoveUnlimited[0] = NULL;
00031     m_IsSequenceMoveUnlimited = false;
00032     m_EmptyStacksFilledBy[0] = NULL;
00033     m_EmptyStacksFilledByType = DEFAULT_EMPTY_STACK_FILL_TYPE;
00034     m_GameName[0] = NULL;
00035     m_MaxNumberOfIterations = -1;
00036     m_MaxDepth = -1;
00037     m_TempTestOrder[0] = NULL;
00038     m_NumberOfTests = 0;
00039     memset(m_TestOrder, NULL, sizeof(int)*FCS_TESTS_NUM);
00040     m_SolvingMethod[0] = NULL;
00041     m_SolvingMethodType = DEFAULT_SOLVING_METHOD;
00042     m_AStarWeights[0] = NULL;
00043     for (int a = 0;a<FC_NUMBER_OF_ASTAR_WEIGHTS ;a++)
00044         m_AStarWeightValues[a] = -1;
00045     m_Seed = 0;
00046     m_MaxStoredStates = -1;
00047     m_OptimizeSolution = false;
00048     m_StateTypeArray[0] = NULL;
00049     m_StateType = DEFAULT_STATE_TYPE;
00050     m_StateStorage[0] = NULL;
00051     m_StackStorage[0] = NULL;
00052     m_Talon[0] = NULL;
00053     m_TalonType = FCS_TALON_NONE;
00054     m_StateStorageType = DEFAULT_STATE_STORAGE_TYPE;
00055     m_StackStorageType = DEFAULT_STACK_STORAGE_TYPE;
00056     m_UserState[0] = NULL;
00057     m_InitialState = NULL;
00058 }
00059 
00060 FCCommandLineArguments::~FCCommandLineArguments()
00061 {
00062 }
00063 
00064 bool FCCommandLineArguments::Parse(int argc, char**argv)
00065 {
00066     int arg;
00067 
00068     for (arg = 1;arg<argc;arg++)
00069     {
00070         /***********************************
00071         HELP
00072         ************************************/
00073         if ((!strcmp(argv[arg], "-h")) || (!strcmp(argv[arg], "--help")))
00074         {
00075             m_DisplayHelp = true;
00076             return true;
00077         }
00078         /***********************************
00079         OUTPUT OPTIONS
00080         ************************************/
00081         else if ((!strcmp(argv[arg], "-p")) || (!strcmp(argv[arg], "--parseable-output")))
00082         {
00083             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_IS_OUTPUT_PARSEABLE;
00084         }
00085         else if ((!strcmp(argv[arg], "-t")) || (!strcmp(argv[arg], "--display-10-as-t")))
00086         {
00087             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_DISPLAY_10_AS_T;
00088         }
00089         else if ((!strcmp(argv[arg], "-c")) || (!strcmp(argv[arg], "--canonized-order-output")))
00090         {
00091             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_CANONIZED_ORDER_OUTPUT;
00092         }
00093         else if ((!strcmp(argv[arg], "-m")) || (!strcmp(argv[arg], "--display-moves")))
00094         {
00095             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_DISPLAY_MOVES;
00096         }
00097         else if ((!strcmp(argv[arg], "-sn")) || (!strcmp(argv[arg], "--standard-notation")))
00098         {
00099             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_USE_STANDARD_NOTATION;
00100         }
00101         else if ((!strcmp(argv[arg], "-sam")) || (!strcmp(argv[arg], "--display-states-and-moves")))
00102         {
00103             m_DebugDisplayInfo->m_DisplayDebugOptions |= (DEBUG_DISPLAY_MOVES | DEBUG_DISPLAY_STATES);
00104         }
00105         else if ((!strcmp(argv[arg], "-pi")) || (!strcmp(argv[arg], "--display-parent-iter")))
00106         {
00107             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_DISPLAY_PARENT_ITERATIONS;
00108         }
00109         else if ((!strcmp(argv[arg], "-dd")) || (!strcmp(argv[arg], "--display-debug")))
00110         {
00111             m_DebugDisplayInfo->m_DisplayDebug = true;
00112         }
00113 
00114         /***********************************
00115         GAME VARIANTS OPTIONS
00116         ************************************/
00117         else if ((!strcmp(argv[arg], "--freecells-num")))
00118         {
00119             arg++;
00120             if (arg != argc)
00121                 m_DebugDisplayInfo->m_NumberOfFreecells = m_NumberOfFreecells = atoi(argv[arg]);
00122         }
00123         else if ((!strcmp(argv[arg], "--stacks-num")))
00124         {
00125             arg++;
00126             if (arg != argc)
00127                 m_DebugDisplayInfo->m_NumberOfStacks = m_NumberOfStacks = atoi(argv[arg]);
00128         }
00129         else if ((!strcmp(argv[arg], "--decks-num")))
00130         {
00131             arg++;
00132             if (arg != argc)
00133                 m_DebugDisplayInfo->m_NumberOfDecks = m_NumberOfDecks = atoi(argv[arg]);
00134         }
00135         else if ((!strcmp(argv[arg], "--sequences-are-built-by")))
00136         {
00137             arg++;
00138             if (arg != argc)
00139                 strcpy(m_SequencesBuiltBy, argv[arg]);
00140         }
00141         else if ((!strcmp(argv[arg], "--sequence-move")))
00142         {
00143             arg++;
00144             if (arg != argc)
00145                 strcpy(m_SequenceMoveUnlimited, argv[arg]);
00146         }
00147         else if (!strcmp(argv[arg], "--empty-stacks-filled-by"))
00148         {
00149             arg++;
00150             if (arg == argc)
00151                 strcpy(m_EmptyStacksFilledBy, argv[arg]);
00152         }
00153         else if (
00154             (!strcmp(argv[arg], "--game")) ||
00155             (!strcmp(argv[arg], "--preset")) ||
00156             (!strcmp(argv[arg], "-g"))
00157             )
00158         {
00159             arg++;
00160             if (arg != argc)
00161                 strcpy(m_GameName, argv[arg]);
00162         }
00163         /***********************************
00164         SOLVING ALGORITHM OPTIONS
00165         ************************************/
00166         else if ((!strcmp(argv[arg], "-mi")) || (!strcmp(argv[arg], "--max-iters")))
00167         {
00168             arg++;
00169             if (arg != argc)
00170                 m_MaxNumberOfIterations = atoi(argv[arg]);
00171         }
00172         else if ((!strcmp(argv[arg], "-md")) || (!strcmp(argv[arg], "--max-depth")))
00173         {
00174             arg++;
00175             if (arg != argc)
00176                 m_MaxDepth = atoi(argv[arg]);
00177         }
00178         else if ((!strcmp(argv[arg], "-to")) || (!strcmp(argv[arg], "--tests-order")))
00179         {
00180             arg++;
00181             if (arg != argc)
00182                 strcpy(m_TempTestOrder, argv[arg]);
00183         }
00184         else if ((!strcmp(argv[arg], "-me")) || (!strcmp(argv[arg], "--method")))
00185         {
00186             arg++;
00187             if (arg != argc)
00188                 strcpy(m_SolvingMethod, argv[arg]);
00189         }
00190         else if ((!strcmp(argv[arg], "-asw")) || (!strcmp(argv[arg], "--a-star-weights")))
00191         {
00192             arg++;
00193             if (arg != argc)
00194                 strcpy(m_AStarWeights, argv[arg]);
00195         }
00196         else if (!strcmp(argv[arg], "--talon"))
00197         {
00198             arg++;
00199             if (arg != argc)
00200                 strcpy(m_Talon, argv[arg]);
00201         }
00202         else if (!strcmp(argv[arg], "-seed"))
00203         {
00204             arg++;
00205             if (arg != argc)
00206                 m_Seed = atoi(argv[arg]);
00207         }
00208         else if ((!strcmp(argv[arg], "-mss")) || (!strcmp(argv[arg], "--max-stored-states")))
00209         {
00210             arg++;
00211             if (arg != argc)
00212                 m_MaxStoredStates = atoi(argv[arg]);
00213         }
00214         else if ((!strcmp(argv[arg], "-opt")) || (!strcmp(argv[arg], "--optimize-solution")))
00215         {
00216             m_OptimizeSolution = true;
00217         }
00218         else if ((!strcmp(argv[arg], "-st")) || (!strcmp(argv[arg], "--state-type")))
00219         {
00220             arg++;
00221             if (arg != argc)
00222                 strcpy(m_StateTypeArray, argv[arg]);
00223         }
00224         else if ((!strcmp(argv[arg], "-stsr")) || (!strcmp(argv[arg], "--state-storage-type")))
00225         {
00226             arg++;
00227             if (arg != argc)
00228                 strcpy(m_StateStorage, argv[arg]);
00229         }
00230         else if ((!strcmp(argv[arg], "-sksr")) || (!strcmp(argv[arg], "--stack-storage-type")))
00231         {
00232             arg++;
00233             if (arg != argc)
00234                 strcpy(m_StackStorage, argv[arg]);
00235         }
00236         /***********************************
00237         RUNTIME DISPLAY OPTIONS
00238         ************************************/
00239         else if ((!strcmp(argv[arg], "-s")) || (!strcmp(argv[arg], "--state-output")))
00240         {
00241             m_DebugDisplayInfo->m_DisplayDebugOptions |= DEBUG_ITERATIVE_STATE_OUTPUT;
00242         }
00243         else
00244         {
00245             break;
00246         }
00247     }
00248 
00249     
00250     FILE * file;
00251 
00252     if ((arg == argc) || (!strcmp(argv[arg], "-")))
00253     {
00254         file = stdin;
00255     }
00256     else if (argv[arg][0] == '=')
00257     {
00258         cerr << "Error! Unknown option '" << argv[arg] << "'.  "
00259              << "Type '" << argv[0] << " --help' for usage information." << endl;
00260         return false;
00261     }
00262     else
00263     {
00264         file = fopen(argv[arg], "r");
00265         if (file == NULL)
00266         {
00267             cerr << "Error!  Could not open file '" << argv[arg] << "' for input. "
00268                  << "Exiting." << endl;
00269             return false;
00270         }
00271     }
00272 
00273     fread(m_UserState, sizeof(char), sizeof(m_UserState)/sizeof(char), file);
00274     fclose(file);
00275 
00276     return true;
00277 }
00278 
00279 bool FCCommandLineArguments::Verify()
00280 {
00281     bool verify = true;
00282 
00283     if (m_DisplayHelp)
00284     {
00285         DisplayHelp();
00286         return false;
00287     }
00288 
00289     if (m_NumberOfFreecells > MAX_NUM_FREECELLS)
00290     {
00291         cerr << "Error! The freecells\' number exceeds the maximum of " 
00292              << MAX_NUM_FREECELLS << endl
00293              << "Recompile the program if you wish to have more." << endl << endl;
00294         verify = false;
00295     }
00296     if (m_NumberOfFreecells < 0)
00297     {
00298         cerr << "Error!  Must have a positive number of freecells!" << endl << endl;
00299         verify = false;
00300     }
00301 
00302     if (m_NumberOfStacks > MAX_NUM_STACKS)
00303     {
00304         cerr << "Error! The stacks' number exceeds the maximum of " 
00305              << MAX_NUM_STACKS << endl
00306              << "Recompile the program if you wish to have more." << endl << endl;
00307         verify = false;
00308     }
00309     if (m_NumberOfStacks < 1)
00310     {
00311         cerr << "Error!  Must have at least one stack of cards!" << endl << endl;
00312         verify = false;
00313     }
00314 
00315     if (m_NumberOfDecks > MAX_NUM_DECKS)
00316     {
00317         cerr << "Error! The decks' number exceeds the maximum of " 
00318              << MAX_NUM_DECKS << endl
00319              << "Recompile the program if you wish to have more." << endl << endl;
00320         verify = false;
00321     }
00322     if (m_NumberOfDecks < 1)
00323     {
00324         cerr << "Error!  Must have at least one deck of cards!" << endl << endl;
00325         verify = false;
00326     }
00327 
00328     if (m_SequencesBuiltBy[0] != NULL)
00329     {
00330         if (!strcmp(m_SequencesBuiltBy, "suit"))
00331         {
00332             m_SequencesBuiltByType = FCS_SEQ_BUILT_BY_SUIT;
00333         }
00334         else if (!strcmp(m_SequencesBuiltBy, "rank"))
00335         {
00336             m_SequencesBuiltByType = FCS_SEQ_BUILT_BY_RANK;
00337         }
00338         else if (!strcmp(m_SequencesBuiltBy, "alternate_color"))
00339         {
00340             m_SequencesBuiltByType = FCS_SEQ_BUILT_BY_ALTERNATE_COLOR;
00341         }
00342         else
00343         {
00344             cerr << "Error! --sequence-are-built-by parameter incorrect" << endl
00345                  << "Please choose from 'suit', 'alternate_color', 'rank'" << endl << endl;
00346             verify = false;
00347         }
00348     }
00349 
00350     if (m_SequenceMoveUnlimited[0] != NULL)
00351     {
00352         if (!strcmp(m_SequenceMoveUnlimited, "unlimited"))
00353         {
00354             m_IsSequenceMoveUnlimited = true;
00355         }
00356         else if (!strcmp(m_SequenceMoveUnlimited, "limited"))
00357         {
00358             m_IsSequenceMoveUnlimited = false;
00359         }
00360         else
00361         {
00362             cerr << "Error! --sequence-move parameter incorrect" << endl
00363                  << "Please choose from 'unlimited' or 'limited'" << endl << endl;
00364             verify = false;
00365         }
00366     }
00367 
00368     if (m_EmptyStacksFilledBy[0] != NULL)
00369     {
00370         if (!strcmp(m_EmptyStacksFilledBy, "kings"))
00371         {
00372             m_EmptyStacksFilledByType  = FCS_ES_FILLED_BY_KINGS_ONLY;
00373         }
00374         else if (!strcmp(m_EmptyStacksFilledBy, "none"))
00375         {
00376             m_EmptyStacksFilledByType  = FCS_ES_FILLED_BY_NONE;
00377         }
00378         else if (!strcmp(m_EmptyStacksFilledBy, "all"))
00379         {
00380             m_EmptyStacksFilledByType  = FCS_ES_FILLED_BY_ANY_CARD;
00381         }
00382         else
00383         {
00384             cerr << "Error! --empty-stacks-filled-by parameter incorrect" << endl
00385                  << "Please choose from 'kings', 'none', 'all'" << endl << endl;
00386             verify = false;
00387         }
00388     }
00389 
00390     if (m_TempTestOrder[0] != NULL)
00391     {
00392         char* ErrorString;
00393         if (FCSApplyTestOrder(m_TestOrder, m_TempTestOrder, &m_NumberOfTests, m_GameName, &ErrorString) != 0)
00394         {
00395             cerr << "Error! " << ErrorString << endl << endl;
00396             verify = false;
00397             delete [] ErrorString;
00398         }
00399     }
00400 
00401     if (m_GameName[0] != NULL)
00402     {
00403         FCSPreset* preset = FCSPreset::GetPresetInfo(m_GameName);
00404         
00405         if(preset == NULL)
00406         {
00407             cerr << "Error!  Unknown game '" << m_GameName << "'!" << endl << endl;
00408             verify = false;
00409         }
00410         else
00411         {
00412             if (preset->m_NumberOfFreecells > MAX_NUM_FREECELLS)
00413             {
00414                 cerr << "Error! \"" << m_GameName << "\"'s freecells\' number exceeds the maximum of " 
00415                      << MAX_NUM_FREECELLS << endl
00416                      << "Recompile the program if you wish to have more." << endl << endl;
00417                 verify = false;
00418             }
00419 
00420             if (preset->m_NumberOfFreecells < MAX_NUM_FREECELLS)
00421             {
00422                 cerr << "Warning! \"" << m_GameName << "\" is using less than the maximum "
00423                      << "number of freecells.  Performance will suffer." << endl
00424                      << "Recompile the program with the exact number of freecells "
00425                      << "for optimal performance." << endl << endl;
00426             }
00427 
00428             m_DebugDisplayInfo->m_NumberOfFreecells = m_NumberOfFreecells = preset->m_NumberOfFreecells;
00429 
00430             if (preset->m_NumberOfStacks > MAX_NUM_STACKS)
00431             {
00432                 cerr << "Error! \"" << m_GameName << "\"'s stacks' number exceeds the maximum of " 
00433                      << MAX_NUM_STACKS << endl
00434                      << "Recompile the program if you wish to have more." << endl << endl;
00435                 verify = false;
00436             }
00437 
00438             if (preset->m_NumberOfStacks < MAX_NUM_STACKS)
00439             {
00440                 cerr << "Warning! \"" << m_GameName << "\" is using less than the maximum "
00441                      << "number of stacks.  Performance will suffer." << endl
00442                      << "Recompile the program with the exact number of stacks "
00443                      << "for optimal performance." << endl << endl;
00444             }
00445 
00446             m_DebugDisplayInfo->m_NumberOfStacks = m_NumberOfStacks = preset->m_NumberOfStacks;
00447 
00448             if (preset->m_NumberOfDecks > MAX_NUM_DECKS)
00449             {
00450                 cerr << "Error! \"" << m_GameName << "\"'s decks' number exceeds the maximum of " 
00451                      << MAX_NUM_DECKS << endl
00452                      << "Recompile the program if you wish to have more." << endl << endl;
00453                 verify = false;
00454             }
00455 
00456             if (preset->m_NumberOfDecks < MAX_NUM_DECKS)
00457             {
00458                 cerr << "Warning! \"" << m_GameName << "\" is using less than the maximum "
00459                      << "number of decks.  Performance will suffer." << endl
00460                      << "Recompile the program with the exact number of decks "
00461                      << "for optimal performance." << endl << endl;
00462             }
00463 
00464             m_DebugDisplayInfo->m_NumberOfDecks = m_NumberOfDecks = preset->m_NumberOfDecks;
00465 
00466             if (m_SequencesBuiltByType != preset->m_SequencesAreBuiltBy)
00467             {
00468                 cerr << "Warning! \"" << m_GameName << "\" has a different default "
00469                      << "value for --sequences-are-built-by.  Using value from command line if "
00470                      << "specified.  Otherwise using value from game preset." << endl << endl;
00471             }
00472 
00473             m_SequencesBuiltByType = preset->m_SequencesAreBuiltBy;
00474 
00475             if ((m_SequenceMoveUnlimited[0] != NULL) && (m_IsSequenceMoveUnlimited != preset->m_UnlimitedSequenceMove))
00476             {
00477                 cerr << "Warning! \"" << m_GameName << "\" has a different default "
00478                      << "value for --sequence-move.  Using value from command line if "
00479                      << "specified.  Otherwise using value from game preset." << endl << endl;
00480             }
00481 
00482             m_IsSequenceMoveUnlimited = preset->m_UnlimitedSequenceMove;
00483 
00484             if (m_EmptyStacksFilledByType != preset->m_EmptyStacksFill)
00485             {
00486                 cerr << "Warning! \"" << m_GameName << "\" has a different default "
00487                      << "value for --empty-stacks-filled-by.  Using value from command line if "
00488                      << "specified.  Otherwise using value from game preset." << endl << endl;
00489             }
00490 
00491             m_EmptyStacksFilledByType = preset->m_EmptyStacksFill;
00492             m_TalonType = m_DebugDisplayInfo->m_TalonType = preset->m_TalonType;
00493 
00494             char* Dummy;
00495             //this shouldn't fail but...
00496             if (FCSApplyTestOrder(m_TestOrder, preset->m_TestOrder, &m_NumberOfTests, m_GameName, &Dummy) != 0)
00497             {
00498                 cerr << "Error! " << Dummy << endl;
00499                 delete [] Dummy;
00500                 verify = false;
00501             }
00502 
00503             delete preset;
00504         }
00505     }
00506         
00507     if (m_MaxNumberOfIterations < 0)
00508     {
00509         cerr << "Warning! It is generally a good idea to set --max_iters to "
00510              << "a value, so the program will not occupy too much memory." << endl << endl;
00511     }
00512 
00513     if (m_MaxDepth >= 0)
00514     {
00515         cerr << "Warning! It's not a good idea to set --max-depth, because that "
00516              << "way several important intermediate states become inaccesible." << endl << endl;
00517     }
00518 
00519     if (m_SolvingMethod[0] != NULL)
00520     {
00521         if (!strcmp(m_SolvingMethod, "dfs"))
00522         {
00523             m_SolvingMethodType = FCS_METHOD_HARD_DFS;
00524         }
00525         else if (!strcmp(m_SolvingMethod, "soft-dfs"))
00526         {
00527             m_SolvingMethodType = FCS_METHOD_SOFT_DFS;
00528         }
00529         else if (!strcmp(m_SolvingMethod, "bfs"))
00530         {
00531             m_SolvingMethodType = FCS_METHOD_BFS;
00532         }
00533         else if (!strcmp(m_SolvingMethod, "a-star"))
00534         {
00535             m_SolvingMethodType = FCS_METHOD_A_STAR;
00536         }
00537         else if (!strcmp(m_SolvingMethod, "random-dfs"))
00538         {
00539             m_SolvingMethodType = FCS_METHOD_RANDOM_DFS;
00540         }
00541         else
00542         {
00543             cerr << "Error!  Unknown solving method '" << m_SolvingMethod << "'." << endl << endl;
00544             verify = false;
00545         }
00546     }
00547 
00548     if (m_AStarWeights[0] != NULL)
00549     {
00550         char *token;
00551         char CopyAStarWeights[FC_SIZE_OF_ASTAR_WEIGHT_ARRAY];
00552         int b = 0, counter = 0;
00553         bool fail = false;
00554 
00555         strcpy(CopyAStarWeights, m_AStarWeights);
00556         token = strtok(CopyAStarWeights, ",\n\0");
00557         if (token != NULL)
00558         {
00559             //check token for non-digit characters
00560             while (token[b] != NULL)
00561             {
00562                 if (((token[b] < '0') || (token[b] < '0')) && ((token[b] != '.')))
00563                 {
00564                     fail = true;
00565                     break;
00566                 }
00567                 b++;
00568             }
00569             if (!fail)
00570                 m_AStarWeightValues[counter++] = atof(token);
00571         }
00572         else
00573         {
00574             cerr << "Error!  Invalid value for --a-star-weights value" << endl << endl;
00575             fail = true;
00576         }
00577 
00578         if (!fail)
00579         {
00580             do 
00581             {
00582                 token = strtok(NULL, ",\n\0");
00583                 if (token != NULL)
00584                 {
00585                     b = 0;
00586                     //check token for non-digit characters
00587                     while (token[b] != NULL)
00588                     {
00589                         if (((token[b] < '0') || (token[b] < '0')) && ((token[b] != '.')))
00590                         {
00591                             cerr << "Error!  Invalid value for --a-star-weights value" << endl << endl;
00592                             fail = true;
00593                             break;
00594                         }
00595                         b++;
00596                     }
00597 
00598                     if (!fail)
00599                         m_AStarWeightValues[counter++] = atof(token);
00600                 }
00601             }
00602             while ((token != NULL) && (counter < FC_NUMBER_OF_ASTAR_WEIGHTS));
00603         }
00604 
00605         if (counter != 5)
00606         {
00607             cerr << "Warning!  Not enough values for --a-star-weights, using default "
00608                  << "values for remaining parameters."  << endl << endl;
00609         }
00610 
00611         if (fail)
00612             verify = false;
00613     }
00614 
00615     if (m_Talon[0] != NULL)
00616     {
00617         if (!strcmp(m_StateTypeArray, "none"))
00618         {
00619             m_TalonType = m_DebugDisplayInfo->m_TalonType = FCS_TALON_NONE;
00620         }
00621         else if (!strcmp(m_StateTypeArray, "gypsy"))
00622         {
00623             m_TalonType = m_DebugDisplayInfo->m_TalonType = FCS_TALON_GYPSY;
00624         }
00625         else if (!strcmp(m_StateTypeArray, "klondike"))
00626         {
00627             m_TalonType = m_DebugDisplayInfo->m_TalonType = FCS_TALON_KLONDIKE;
00628         }
00629         else
00630         {
00631             cerr << "Error!  Unknown talon type '" << m_StateTypeArray << "'." << endl << endl;
00632             verify = false;
00633         }
00634     }
00635 
00636     if (m_StateTypeArray[0] != NULL)
00637     {
00638         if (!strcmp(m_StateTypeArray, "debug"))
00639         {
00640             GlobalStateType = m_StateType = FC_DEBUG_STATE;
00641         }
00642         else if (!strcmp(m_StateTypeArray, "compact"))
00643         {
00644             GlobalStateType = m_StateType = FC_COMPACT_STATE;
00645         }
00646         else if (!strcmp(m_StateTypeArray, "indirect"))
00647         {
00648             GlobalStateType = m_StateType = FC_INDIRECT_STATE;
00649         }
00650         else
00651         {
00652             cerr << "Error!  Unknown state type '" << m_StateTypeArray << "'." << endl << endl;
00653             verify = false;
00654         }
00655     }
00656 
00657     if (m_TalonType != FCS_TALON_NONE)
00658     {
00659         switch(m_StateType)
00660         {
00661         case FC_DEBUG_STATE:
00662             GlobalStateType = m_StateType = FC_TALON_DEBUG_STATE;
00663             break;
00664         case FC_COMPACT_STATE:
00665             GlobalStateType = m_StateType = FC_TALON_COMPACT_STATE;
00666             break;
00667         case FC_INDIRECT_STATE:
00668             GlobalStateType = m_StateType = FC_TALON_INDIRECT_STATE;
00669             break;
00670         }
00671     }
00672 
00673     if (m_StateStorage[0] != NULL)
00674     {
00675         if (!strcmp(m_StateStorage, "avl"))
00676         {
00677             m_StateStorageType = FC_AVL_TREE;
00678         }
00679         else if (!strcmp(m_StateStorage, "avl_rb"))
00680         {
00681             m_StateStorageType = FC_AVL_RED_BLACK_TREE;
00682         }
00683         else if (!strcmp(m_StateStorage, "red_black"))
00684         {
00685             m_StateStorageType = FC_RED_BLACK_TREE;
00686         }
00687         else if (!strcmp(m_StateStorage, "glib_tree"))
00688         {
00689             m_StateStorageType = FC_GLIB_TREE;
00690         }
00691         else if (!strcmp(m_StateStorage, "glib_hash"))
00692         {
00693             m_StateStorageType = FC_GLIB_HASH;
00694         }
00695         else if (!strcmp(m_StateStorage, "internal"))
00696         {
00697             m_StateStorageType = FC_INTERNAL_HASH;
00698         }
00699         else if (!strcmp(m_StateStorage, "indirect"))
00700         {
00701             if ((m_StateType != FC_INDIRECT_STATE) && (m_StateType != FC_TALON_INDIRECT_STATE))
00702             {
00703                 cerr << "Error!  Indirect storage must use indirect states!" << endl << endl;
00704                 verify = false;
00705             }
00706             else
00707             {
00708                 m_StateStorageType = FC_INDIRECT_HASH;
00709             }
00710         }
00711         else
00712         {
00713             cerr << "Error!  Unknown state storage type '" << m_StateTypeArray << "'." << endl << endl;
00714             verify = false;
00715         }
00716     }
00717 
00718     if (m_StackStorage[0] != NULL)
00719     {
00720         if (!strcmp(m_StackStorage, "avl"))
00721         {
00722             m_StackStorageType = FC_AVL_TREE;
00723         }
00724         else if (!strcmp(m_StackStorage, "avl_rb"))
00725         {
00726             m_StackStorageType = FC_AVL_RED_BLACK_TREE;
00727         }
00728         else if (!strcmp(m_StackStorage, "red_black"))
00729         {
00730             m_StackStorageType = FC_RED_BLACK_TREE;
00731         }
00732         else if (!strcmp(m_StackStorage, "glib_tree"))
00733         {
00734             m_StackStorageType = FC_GLIB_TREE;
00735         }
00736         else if (!strcmp(m_StackStorage, "glib_hash"))
00737         {
00738             m_StackStorageType = FC_GLIB_HASH;
00739         }
00740         else if (!strcmp(m_StackStorage, "internal"))
00741         {
00742             m_StackStorageType = FC_INTERNAL_HASH;
00743         }
00744         else
00745         {
00746             cerr << "Error!  Unknown stack storage type '" << m_StateTypeArray << "'." << endl << endl;
00747             verify = false;
00748         }
00749     }
00750 
00751     if (m_DebugDisplayInfo->m_DisplayDebugOptions & (DEBUG_USE_STANDARD_NOTATION | (!DEBUG_DISPLAY_MOVES)))
00752     {
00753         cerr << "Warning! --standard-notation must be used in conjunction with "
00754              << "--display-moves.  It will be ignored." << endl << endl;
00755         m_DebugDisplayInfo->m_DisplayDebugOptions &= !DEBUG_USE_STANDARD_NOTATION;
00756     }
00757 
00758     if (m_UserState[0] != NULL)
00759     {
00760         if (verify)
00761         {
00762             FCSCard *MisplacedCard = NULL;
00763 
00764             m_InitialState = CreateInitialState(m_UserState, m_NumberOfFreecells, 
00765                                                 m_NumberOfStacks, m_NumberOfDecks, m_TalonType);
00766 
00767             int Valid = m_InitialState->CheckStateValidity(m_NumberOfFreecells, m_NumberOfStacks,
00768                                                     m_NumberOfDecks, &MisplacedCard, m_TalonType);
00769             if (Valid != 0)
00770             {
00771                 char CardString[10];
00772 
00773                 verify = false;
00774 
00775                 MisplacedCard->Perl2User(CardString, (m_DebugDisplayInfo->m_DisplayDebugOptions & DEBUG_DISPLAY_10_AS_T), 
00776                                         m_DebugDisplayInfo->m_DisplayDebug);
00777 
00778                 delete m_InitialState;
00779                 m_InitialState = NULL;
00780 
00781                 switch(Valid)
00782                 {
00783                 case 1:
00784                     cerr << "Error!  There's a missing card: " << CardString << endl << endl;
00785                     break;
00786                 case 2:
00787                     cerr << "Error!  There's an extra card: " << CardString << endl << endl;
00788                     break;
00789                 case 3:
00790                     cerr << "Error!  There's an empty slot in one of the stacks" << endl << endl;
00791                     break;
00792                 }
00793             }
00794 
00795             if (MisplacedCard != NULL)
00796                 delete MisplacedCard;
00797         }
00798     }
00799 
00800     if (!verify)
00801         delete m_DebugDisplayInfo;
00802 
00803     return verify;
00804 
00805 }
00806 
00807 int FCCommandLineArguments::GetMaxDepth()
00808 {
00809     return m_MaxDepth;
00810 }
00811 
00812 int FCCommandLineArguments::GetMaxNumberOfIterations()
00813 {
00814     return m_MaxNumberOfIterations;
00815 }
00816 
00817 int FCCommandLineArguments::GetNumberOfTests()
00818 {
00819     return m_NumberOfTests;
00820 }
00821 
00822 char FCCommandLineArguments::GetTestOrderNumber(int number)
00823 {
00824     return m_TestOrder[number];
00825 }
00826 
00827 int FCCommandLineArguments::GetNumberOfFreecells()
00828 {
00829     return m_NumberOfFreecells;
00830 }
00831 
00832 int FCCommandLineArguments::GetNumberOfStacks()
00833 {
00834     return m_NumberOfStacks;
00835 }
00836 
00837 int FCCommandLineArguments::GetNumberOfDecks()
00838 {
00839     return m_NumberOfDecks;
00840 }
00841 
00842 int FCCommandLineArguments::GetMaxStoredStates()
00843 {
00844     return m_MaxStoredStates;
00845 }
00846 
00847 int FCCommandLineArguments::GetSeed()
00848 {
00849     return m_Seed;
00850 }
00851 
00852 BuildSequenceByEnum FCCommandLineArguments::GetSequenceBuildType()
00853 {
00854     return m_SequencesBuiltByType;
00855 }
00856 
00857 bool FCCommandLineArguments::GetIsSequenceMoveUnlimited()
00858 {
00859     return m_IsSequenceMoveUnlimited;
00860 }
00861 
00862 FCEmptyStacksFillType FCCommandLineArguments::GetEmptyStacksFill()
00863 {
00864     return m_EmptyStacksFilledByType;
00865 }
00866 
00867 char* FCCommandLineArguments::GetGameName()
00868 {
00869     return (char*)&m_GameName;
00870 }
00871 
00872 char* FCCommandLineArguments::GetAStarWeights()
00873 {
00874     return m_AStarWeights;
00875 }
00876 
00877 double FCCommandLineArguments::GetAStarWeightValues(int number)
00878 {
00879     return m_AStarWeightValues[number];
00880 }
00881 
00882 FCSolvingMethodType FCCommandLineArguments::GetSolvingMethodType()
00883 {
00884     return m_SolvingMethodType;
00885 }
00886 
00887 FCStateType FCCommandLineArguments::GetStateType()
00888 {
00889     return m_StateType;
00890 }
00891 
00892 FCStorageType FCCommandLineArguments::GetStateStorageType()
00893 {
00894     return m_StateStorageType;
00895 }
00896 
00897 FCStorageType FCCommandLineArguments::GetStackStorageType()
00898 {
00899     return m_StackStorageType;
00900 }
00901 
00902 FCSTalonType FCCommandLineArguments::GetTalonType()
00903 {
00904     return m_TalonType;
00905 }
00906 
00907 bool FCCommandLineArguments::GetOptimizeSolution()
00908 {
00909     return m_OptimizeSolution;
00910 }
00911 
00912 FCSStateWithLocations* FCCommandLineArguments::GetInitialState()
00913 {
00914     return m_InitialState;
00915 }
00916 
00917 FCSDebugDisplayInfo* FCCommandLineArguments::GetDebugDisplayInfo()
00918 {
00919     return m_DebugDisplayInfo;
00920 }
00921 
00922 /*
00923 Notes:
00924 
00925 I took out --iter-output becuase it wasn't being used.  (I was used in the original
00926 freecell solver for command handling, which I'm not doing at the moment (if ever)
00927 
00928 Made --state-output useful for all FCSStateWithLocations types
00929 
00930 Took out signals
00931 
00932 Added the following parameters:
00933     -dd --display-debug
00934     -st --state-type
00935     -stsr --state-storage-type
00936     -sksr --stack-storage-type
00937 */
00938 
00939 void DisplayHelp()
00940 {
00941     cout << "CppFreecellSolver [options] board_file" << endl << endl
00942          << "If board_file is - or unspecified reads standard input" << endl << endl
00943          << "Available Options:" << endl
00944          << "-h   --help" << endl
00945          << "\tdisplay this help screen" << endl
00946          << "-s   --state-output" << endl
00947          << "\talso output the state in every state that is checked" << endl
00948          << "-p   --parseable-output" << endl
00949          << "\tOutput the states in a format that is friendly to perl, grep and friends." << endl
00950          << "-c   --canonized-order-output" << endl
00951          << "\tOutput the stacks and freecells according to their canonic order." << endl
00952          << "\t(That means that stacks and freecells won't retain their place.)" << endl
00953          << "-t   --display-10-as-t" << endl
00954          << "\tDisplay the card 10 as a capital T instead of \"10\"." << endl
00955          << "-m   --display-moves" << endl
00956          << "\tDisplay the moves instead of the intermediate states." << endl
00957          << "-sam --display-states-and-moves" << endl
00958          << "\tDisplay both intermediate states and moves." << endl
00959          << "-sn  --standard-notation" << endl
00960          << "\tDisplay the moves in standard (non-verbose) notation."
00961          << "\t(Applicable only if -m was specified)" << endl
00962          << "-pi  --display-parent-iter" << endl
00963          << "\tDisplay the index of the parent iteration of each state in the run-time dump" << endl << endl
00964          << "-dd  --display-debug" << endl
00965          << "\tDisplays all debug information" << endl
00966          << "--freecells-num [Freecells\' Number]" << endl
00967          << "\tThe number of freecells present in the board." << endl
00968          << "--stacks-num [Stacks\' Number]" << endl
00969          << "\tThe number of stacks present in the board." << endl
00970          << "--decks-num [Decks\' Number]" << endl
00971          << "\tThe number of decks in the board." << endl
00972          << "--sequences-are-built-by {suit|alternate_color|rank}" << endl
00973          << "\tSpecifies the type of sequence" << endl
00974          << "--sequence-move {limited|unlimited}" << endl
00975          << "\tSpecifies whether the sequence move is limited by the number of" << endl
00976          << "\tfreecells or vacant stacks or not." << endl
00977          << "--empty-stacks-filled-by {kings|none|all}" << endl
00978          << "\tSpecifies which cards can fill empty stacks." << endl
00979          << "--game [game]   --preset [game]  -g [game]" << endl
00980          << "\tSpecifies the type of game. (Implies several of the game settings options above.)  Available presets:" << endl
00981          << "\tbakers_dozen       - Baker\'s Dozen" << endl
00982          << "\tbakers_game        - Baker\'s Game" << endl
00983          << "\tbeleaguered_castle - Beleaguered Castle" << endl
00984          << "\tcitadel            - Citadel" << endl
00985          << "\tcruel              - Cruel" << endl
00986          << "\tder_katz           - Der Katzenschwanz" << endl
00987          << "\tdie_schlange       - Die Schlange" << endl
00988          << "\teight_off          - Eight Off" << endl
00989          << "\tforecell           - Forecell" << endl
00990          << "\tfreecell           - Freecell" << endl
00991          << "\tgood_measure       - Good Measure" << endl
00992          << "\tko_bakers_game     - Kings\' Only Baker\'s Game" << endl
00993          << "\trelaxed_freecell   - Relaxed Freecell" << endl
00994          << "\trelaxed_seahaven   - Relaxed Seahaven Towers" << endl
00995          << "\tseahaven           - Seahaven Towers" << endl
00996          << "\tsimple_simon       - Simple Simon" << endl
00997          << "\tstreets_and_alleys - Streets and Alleys" << endl << endl
00998          << "-md [depth]       --max-depth [depth]" << endl
00999          << "\tSpecify a maximal search depth for the solution process." << endl
01000          << "-mi [iter_num]    --max-iters [iter_num]" << endl
01001          << "\tSpecify a maximal number of iterations number." << endl
01002          << "-mss [states_num] --max-stored-states [states_num]" << endl
01003          << "\tSpecify the maximal number of states stored in memory." << endl
01004          << "-to [tests_order]   --tests-order  [tests_order]" << endl
01005          << "\tSpecify a test order string. Each test is represented by one character." << endl
01006          << "\tValid tests:" << endl
01007          << "\t\tFreecell Tests:" << endl << endl
01008          << "\t\t'0' - put top stack cards in the foundations." << endl
01009          << "\t\t'1' - put freecell cards in the foundations." << endl
01010          << "\t\t'2' - put freecell cards on top of stacks." << endl
01011          << "\t\t'3' - put non-top stack cards in the foundations." << endl
01012          << "\t\t'4' - move stack cards to different stacks." << endl
01013          << "\t\t'5' - move stack cards to a parent card on the same stack." << endl
01014          << "\t\t'6' - move sequences of cards onto free stacks." << endl
01015          << "\t\t'7' - put freecell cards on empty stacks." << endl
01016          << "\t\t'8' - move cards to a different parent." << endl
01017          << "\t\t'9' - empty an entire stack into the freecells." << endl << endl
01018          << "\tSimple Simon Tests (used only if simple_simon game is selected):" << endl
01019          << "\t\t'0' - move a full sequence to the foundations." << endl
01020          << "\t\t'1' - move a sequence to a true parent of his." << endl
01021          << "\t\t'2' - move a whole stack sequence to a false parent (in order to clear the stack)" << endl
01022          << "\t\t'3' - move a sequence to a true parent that has some cards above it." << endl
01023          << "\t\t'4' - move a sequence with some cards above it to a true parent." << endl
01024          << "\t\t'5' - move a sequence with a junk sequence above it to a true parent" << endl
01025          << "\t\tthat has some cards above it." << endl
01026          << "\t\t'6' - move a whole stack sequence to a false parent which has some cards above it." << endl
01027          << "\t\t'7' - move a sequence to a parent on the same stack." << endl << endl
01028          << "\t\tTests are grouped with parenthesis or square brackets. Each group" << endl
01029          << "\t\twill be randomized as a whole by the random-dfs scan." << endl << endl
01030          << "-me [solving_method]   --method [solving_method]" << endl
01031          << "\tSpecify a solving method. Available methods are:" << endl
01032          << "\t\t\"a-star\" - A*" << endl
01033          << "\t\t\"bfs\" - Breadth-First Search" << endl
01034          << "\t\t\"dfs\" - Depth-First Search (default)" << endl
01035          << "\t\t\"random-dfs\" - A randomized DFS" << endl
01036          << "\t\t\"soft-dfs\" - \"Soft\" DFS" << endl << endl
01037          << "-asw [A* Weights]   --a-star-weight [A* Weights]" << endl
01038          << "\tSpecify weights for the A* scan, assuming it is used. The parameter" << endl
01039          << "\tshould be a comma-separated list of numbers, each one is proportional" << endl
01040          << "\tto the weight of its corresponding test." << endl << endl
01041          << "\tThe numbers are, in order:" << endl
01042          << "\t1. The number of cards out." << endl
01043          << "\t2. The maximal sequence move." << endl
01044          << "\t3. The number of cards under sequences." << endl
01045          << "\t4. The length of the sequences which are found over renegade cards."
01046          << "\t5. The depth of the board in the solution." << endl << endl
01047          << "-seed [seed_number]" << endl
01048          << "\tSet the seed for the random number generator used by the \"random-dfs\" scan." << endl
01049          << "-opt  --optimize-solution" << endl
01050          << "\tTry and optimize the solution for a small number of moves." << endl
01051          << "-st   --state-type {debug|compact|indirect}" << endl
01052          << "\tType of state used to solve board." << endl
01053          << "-stsr --state-storage-type" << endl
01054          << "\tSpecify a storage method for the states.  Available methods are:" << endl
01055          << "\t\t\"avl\" - an avl tree" << endl
01056          << "\t\t\"avl_rb\" - a red-black avl tree" << endl
01057          << "\t\t\"red_black\" - a red-black tree" << endl
01058          << "\t\t\"glib_tree\" - a glib tree" << endl
01059          << "\t\t\"glib_hash\" - a glib hash" << endl
01060          << "\t\t\"internal\" - internal storage" << endl << endl
01061          << "-sksr --stack-storage-type" << endl
01062          << "\tSpecify a storage method for the stacks.  Available methods are:" << endl
01063          << "\t\t\"avl\" - an avl tree" << endl
01064          << "\t\t\"avl_rb\" - a red-black avl tree" << endl
01065          << "\t\t\"red_black\" - a red-black tree" << endl
01066          << "\t\t\"glib_tree\" - a glib tree" << endl
01067          << "\t\t\"glib_hash\" - a glib hash" << endl
01068          << "\t\t\"internal\" - internal storage" << endl
01069          << endl << endl << endl
01070          << "C++ Freecell Solver was written by Michael Mann" << endl
01071          << "Send comments and suggestions to mmann78@adelphia.net" << endl
01072          << endl;
01073 }

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