// // Created by maximilian on 7/13/23. // #include #include #include #include #include #include "game_state.h" #include "download.h" #include "myassert.h" #include "cli_interface.h" namespace Hanabi { void download(std::variant game_id, int turn) { auto game = Download::get_game(game_id, turn); std::cout << "Analysing state: " << std::endl << *game << std::endl; auto res = game->evaluate_state(); std::cout.precision(10); std::cout << std::endl; std::cout << "Probability with optimal play: " << res << std::endl; std::cout << "Enumerated " << game->enumerated_states() << " states" << std::endl; std::cout << "Visited " << game->position_tablebase().size() << " unique game states. " << std::endl; unsigned long biggest_key = 0; for(const auto& [key, prob] : game->position_tablebase()) { biggest_key = std::max(biggest_key, key); } std::cout << "Biggest key generated is " << biggest_key << std::endl; std::cout << std::endl; auto game_shared = std::shared_ptr(game.release()); auto states = game_shared->possible_next_states(0, false); cli(game_shared); } void print_sizes() { std::cout << "size of card -> hand map: " << sizeof(HanabiState<5, 3, 4>) << std::endl; unsigned exp = 32; std::cout << "Pair size: " << sizeof(std::pair) << std::endl; std::cout << sizeof(boost::rational) << std::endl; std::cout << (1ul << exp) << std::endl; } void print_usage(const char* program_name) { std::cout << "Usage: " << program_name << " GAME_ID TURN" << std::endl; } } #define CHECK(test, condition) if (!(condition)) { std::cerr << "Test " << (test) << " failed." << std::endl; } else { std::cout << "Test " << (test) << " succeeded." << std::endl; } void test() { { auto game = Download::get_game("in/1005195", 43); auto res = game->evaluate_state(); CHECK("1005195", res == Hanabi::probability_t (7,8)); } } void check_games(unsigned num_players, unsigned max_draw_pile_size, unsigned first_game = 0, unsigned last_game = 9999) { std::vector> winning_percentages(last_game + 2); for(size_t draw_pile_size = 0; draw_pile_size <= max_draw_pile_size; draw_pile_size++) { Hanabi::probability_t total_chance = 0; const std::string output_fname = "games_" + std::to_string(num_players) + "p_draw_size_" + std::to_string(draw_pile_size) + ".txt"; std::ofstream file (output_fname); for(size_t game_id = first_game; game_id <= last_game; game_id++) { const std::string input_fname = "json/" + std::to_string(num_players) + "p/" + std::to_string(game_id) + ".json"; auto game = Download::get_game(input_fname.c_str(), 50, draw_pile_size); const Hanabi::probability_t chance = game->evaluate_state(); winning_percentages[game_id].push_back(chance); if(chance != 1) { file << "Game " << game_id << ": " << chance << std::endl; file << *game << std::endl << std::endl; } std::cout << "Finished game " << game_id << " with draw pile size " << draw_pile_size << ": " << chance << std::endl; total_chance += chance; } const Hanabi::probability_t total_average = total_chance / (last_game - first_game + 1); winning_percentages.back().push_back(total_average); file << "Total chance found over " << last_game - first_game + 1 << " many games: " << total_average << std::endl; file.close(); } const std::string results_file_name {"results_" + std::to_string(num_players) + "p.txt"}; std::ofstream results_file (results_file_name); results_file << "game_id, "; for(size_t draw_pile_size = 0; draw_pile_size <= max_draw_pile_size; draw_pile_size++) { results_file << std::to_string(draw_pile_size) << ", "; } results_file << "\n"; for(size_t game_id = first_game; game_id <= last_game; game_id++) { results_file << game_id << ", "; for(size_t draw_pile_size = 0; draw_pile_size <= max_draw_pile_size; draw_pile_size++) { results_file << winning_percentages[game_id][draw_pile_size] << ", "; } results_file << std::endl; } results_file << "total, "; for(size_t draw_pile_size = 0; draw_pile_size <= max_draw_pile_size; draw_pile_size++) { results_file << winning_percentages.back()[draw_pile_size] << ", "; } results_file << std::endl; results_file.close(); } int main(int argc, char *argv[]) { #ifndef NDEBUG test(); #endif if(argc == 3) { std::string game(argv[1]); std::string turn (argv[2]); try { Hanabi::download(std::stoi(game), std::stoi(turn)); } catch(std::invalid_argument&) { Hanabi::download(game.c_str(), std::stoi(turn)); } } else if (argc == 2) { int player_count = std::stoi(argv[1]); if (player_count == 3) { check_games(3, 10); } else if (player_count == 4) { check_games(4, 9); } else if (player_count == 5) { check_games(5, 9); } else if (player_count == 2) { check_games(2, 10); } } else { Hanabi::print_usage(argv[0]); } return 0; }