#ifndef DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H #define DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H #include #include #include "hanabi_types.hpp" namespace Hanabi { enum class GameStateSpecType { turn = 0, draw_pile_size = 1, }; struct CLIParms { /** * The data source for the game to be analysed. * If of type int, assumed to be a game ID from hanab.live * If of type string, assumed to be a (relative) filename to a game in hanab.live json format, * see https://raw.githubusercontent.com/Hanabi-Live/hanabi-live/main/misc/example_game_with_comments.jsonc * for a format specification. */ std::variant game {}; /** * Definition of a 'winning' game, i.e. what score (number of cards played) is considered * to be winning. * If std::nullopt, then the maximum score of the game will be used. */ boost::optional score_goal {}; /** * Whether game_state_spec denotes a turn number or draw pile size. */ GameStateSpecType game_state_spec_type { GameStateSpecType::draw_pile_size }; /** * Either a turn number or a draw pile size, depending on game_state_spec_type. * If this represents a draw pile size, we mean the first turn of the game where the draw pile * had the given size, i.e. the turn immediately after drawing a card. * If this represents a turn, we just mean the corresponding turn number, starting numbering at 1 * (since this is also the case on hanab.live) * Thus, a turn number of 0 is undefined and a turn number of 1 corresponds to no actions taken in the game. */ unsigned game_state_spec { 5 }; /** * Whether to launch an interactive exploration shell for the game state after performing analysis. */ boost::optional interactive {}; /** * If true, deactivates non-essential output (to cout). */ bool quiet { false }; /** * If this holds std::monostate, then all clue numbers are evaluated. * Otherwise, the specified clue modifier is applied (relative to actual number of clues). * Thus, setting this to 0 has no effect. */ std::variant clue_spec {static_cast(0)}; /** * If true, then all states corresponding to smaller draw pile sizes */ bool recursive { false }; }; /** * @brief Get an output stream that is std::cout or a Null-Stream. * @param quiet If true, NullStream is returned, otherwise std::cout */ std::ostream & quiet_ostream(bool quiet); constexpr int download_failed = 1; constexpr int state_unreachable = 2; /** * Parse parameters from command-line arguments. * @param argc Number of arguments * @param argv Array of C-Style strings, where argv[0] is ignored (as the program name). * * @note This is exactly the signature of the main() method */ std::optional parse_parms(int argc, char *argv[]); /** * @brief Execute parsed parameters. */ int run_cli(CLIParms parms); } #endif //DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H