#ifndef DYNAMIC_PROGRAM_DOWNLOAD_H #define DYNAMIC_PROGRAM_DOWNLOAD_H #include #include #include #include #include "game_state.h" // This helper function deduces the type and assigns the value with the matching key template void extract( boost::json::object const& obj, T& t, std::string_view key ) { t = value_to( obj.at( key ) ); } namespace Hanabi { Card tag_invoke(boost::json::value_to_tag, boost::json::value const &jv) { Hanabi::Card card{}; boost::json::object const &obj = jv.as_object(); extract(obj, card.rank, "rank"); extract(obj, card.suit, "suitIndex"); card.rank = 5 - card.rank; return card; } void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, Hanabi::Card const &card) { jv = {{"suitIndex", card.suit}, {"rank", card.rank}}; } } std::vector parse_deck(const boost::json::value& deck_json) { auto deck = boost::json::value_to>(deck_json); std::array, 6> next_copy_indices {}; for(size_t i = 0; i < deck.size(); i++) { auto &card = deck[i]; assert(card.rank < 5); assert(card.rank >= 0); assert(card.suit < 6); assert(card.suit >= 0); card.index = i; card.copy = next_copy_indices[card.suit][card.rank]; next_copy_indices[card.suit][card.rank]++; } return deck; } boost::json::object download_game_json(int game_id) { std::string request_str = "https://hanab.live/export/" + std::to_string(game_id); cpr::Response r = cpr::Get(cpr::Url(request_str)); if (r.header["content-type"] != "application/json; charset=utf-8") { return {}; } return boost::json::parse(r.text).as_object(); } void download_game(int game_id) { boost::json::object game = download_game_json(game_id); std::cout << game << std::endl; const auto deck = parse_deck(game.at("deck")); const unsigned num_players = game.at("players").as_array().size(); for(const auto& card : deck) { std::cout << card << std::endl; } std::cout << num_players; } #endif // DYNAMIC_PROGRAM_DOWNLOAD_H