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
00072
00073 if ((!strcmp(argv[arg], "-h")) || (!strcmp(argv[arg], "--help")))
00074 {
00075 m_DisplayHelp = true;
00076 return true;
00077 }
00078
00079
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
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
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
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
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
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
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
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
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 }