Endgame-Analyzer/include/command_line_interface.h
2023-11-16 16:20:04 +01:00

95 lines
3.1 KiB
C++

#ifndef DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H
#define DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H
#include <variant>
#include <boost/optional.hpp>
#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<int, std::string> 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<uint8_t> 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<bool> 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<std::monostate, clue_t> clue_spec{static_cast<clue_t>(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<CLIParms> parse_parms(int argc, char *argv[]);
/**
* @brief Execute parsed parameters.
*/
int run_cli(CLIParms const &parms);
}
#endif //DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H