Endgame-Analyzer/include/command_line_interface.h

115 lines
3.9 KiB
C
Raw Permalink Normal View History

#ifndef DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H
#define DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H
#include <variant>
#include <boost/optional.hpp>
2023-11-15 23:07:39 +01:00
#include "hanabi_types.hpp"
2023-11-16 16:20:04 +01:00
namespace Hanabi
{
enum class GameStateSpecType
{
turn = 0, draw_pile_size = 1, };
2023-11-16 16:20:04 +01:00
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.
*/
2023-11-16 16:20:04 +01:00
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<unsigned int> score_goal{};
/**
* Whether game_state_spec denotes a turn number or draw pile size.
*/
2023-11-16 16:20:04 +01:00
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.
*/
2023-11-16 16:20:04 +01:00
unsigned game_state_spec{5};
/**
* Whether to launch an interactive exploration shell for the game state after performing analysis.
*/
2023-11-16 16:20:04 +01:00
boost::optional<bool> interactive{};
/**
* If true, deactivates non-essential output (to cout).
*/
2023-11-16 16:20:04 +01:00
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.
*/
2023-11-16 16:20:04 +01:00
std::variant<std::monostate, clue_t> clue_spec{static_cast<clue_t>(0)};
/**
* If true, then all states corresponding to smaller draw pile sizes are evaluated as well.
*/
2023-11-16 16:20:04 +01:00
bool recursive{false};
/**
* If true, lists all possible actions and their win probabilities in the specified
* and future game states, including suboptimal ones.
*/
bool list_actions{false};
/**
* If set to true, only roughly half of the game states will be stored in the internal lookup table.
* This results in roughly halving memory consumption at the cost of roughly a factor 3-5 in execution speed
* (the slowdown is theoretically bounded to visiting at most 9 times the number of states if this option is activated).
* You should typically never need this, unless you are very specifically short on memory and.
* */
bool save_memory{false};
/**
* If true, prints version information of the program and exits immediately.
*/
bool version_info{false};
};
/**
* @brief Get an output stream that is std::cout or a Null-Stream.
* @param quiet If true, NullStream is returned, otherwise std::cout
*/
2023-11-16 16:20:04 +01:00
std::ostream &quiet_ostream(bool quiet);
constexpr int download_failed = 1;
constexpr int state_unreachable = 2;
2024-01-13 14:36:36 +01:00
constexpr int out_of_memory = 3;
/**
* 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.
*/
2023-11-16 16:20:04 +01:00
int run_cli(CLIParms const &parms);
}
#endif //DYNAMIC_PROGRAM_COMMAND_LINE_INTERFACE_H