use own header for producing state to reduce compilation time
This commit is contained in:
parent
9887d104b8
commit
04e071c97c
4 changed files with 120 additions and 78 deletions
|
@ -26,6 +26,8 @@ add_executable(endgame-analyzer src/main.cpp src/state_explorer.cpp src/download
|
||||||
include/game_interface.h
|
include/game_interface.h
|
||||||
src/hanabi_types.cpp
|
src/hanabi_types.cpp
|
||||||
src/game_interface.cpp
|
src/game_interface.cpp
|
||||||
|
include/make_state.h
|
||||||
|
src/make_state.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(endgame-analyzer cpr)
|
target_link_libraries(endgame-analyzer cpr)
|
||||||
|
|
33
include/make_state.h
Normal file
33
include/make_state.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef DYNAMIC_PROGRAM_MAKE_STATE_H
|
||||||
|
#define DYNAMIC_PROGRAM_MAKE_STATE_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "game_interface.h"
|
||||||
|
|
||||||
|
namespace Hanabi
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Produces a game state from specified parms.
|
||||||
|
* @param num_suits: Has to be in [3,6]
|
||||||
|
* @param num_players Has to be in [2,6]
|
||||||
|
* @param deck A list of cards with at most as many suits as num_suits
|
||||||
|
* @param score_goal What is considered as an optimal score for this game state.
|
||||||
|
* If null, the maximum score is inserted
|
||||||
|
* @return Pointer to created game state, wrapped into abstract interface
|
||||||
|
*
|
||||||
|
* @note Since the implementation of the actual game state (the concrete class derived from HanabiStateIF),
|
||||||
|
* is heavily templated, this function has its own header + source file to reduce compilation time
|
||||||
|
* for all components using this, since there is now only one place where the templated implementation
|
||||||
|
* is actually compiled and has not be recompiled upon other program parts changing.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<Hanabi::HanabiStateIF> make_game_state(
|
||||||
|
std::size_t num_suits,
|
||||||
|
Hanabi::player_t num_players,
|
||||||
|
std::vector<Hanabi::Card> const &deck,
|
||||||
|
std::optional<uint8_t> score_goal = std::nullopt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DYNAMIC_PROGRAM_MAKE_STATE_H
|
|
@ -2,7 +2,7 @@
|
||||||
#include <cpr/cpr.h>
|
#include <cpr/cpr.h>
|
||||||
|
|
||||||
#include "parse_game.h"
|
#include "parse_game.h"
|
||||||
#include "game_state.h"
|
#include "make_state.h"
|
||||||
|
|
||||||
#include "download.h"
|
#include "download.h"
|
||||||
|
|
||||||
|
@ -27,82 +27,6 @@ namespace Download {
|
||||||
return boost::json::parse(game_json).as_object();
|
return boost::json::parse(game_json).as_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Hanabi::HanabiStateIF> get_base_state(
|
|
||||||
std::size_t num_suits,
|
|
||||||
Hanabi::player_t num_players,
|
|
||||||
std::vector<Hanabi::Card> const & deck,
|
|
||||||
std::optional<uint8_t> score_goal) {
|
|
||||||
uint8_t actual_score_goal = score_goal.value_or(5 * num_suits);
|
|
||||||
switch(num_players) {
|
|
||||||
case 2:
|
|
||||||
switch(num_suits) {
|
|
||||||
case 3:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,2,5>(deck, actual_score_goal));
|
|
||||||
case 4:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,2,5>(deck, actual_score_goal));
|
|
||||||
case 5:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,2,5>(deck, actual_score_goal));
|
|
||||||
case 6:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,2,5>(deck, actual_score_goal));
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
switch(num_suits) {
|
|
||||||
case 3:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,3,5>(deck, actual_score_goal));
|
|
||||||
case 4:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,3,5>(deck, actual_score_goal));
|
|
||||||
case 5:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,3,5>(deck, actual_score_goal));
|
|
||||||
case 6:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,3,5>(deck, actual_score_goal));
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
switch(num_suits) {
|
|
||||||
case 3:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,4,4>(deck, actual_score_goal));
|
|
||||||
case 4:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,4,4>(deck, actual_score_goal));
|
|
||||||
case 5:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,4,4>(deck, actual_score_goal));
|
|
||||||
case 6:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,4,4>(deck, actual_score_goal));
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
|
||||||
}
|
|
||||||
case 5:
|
|
||||||
switch(num_suits) {
|
|
||||||
case 3:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,5,4>(deck, actual_score_goal));
|
|
||||||
case 4:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,5,4>(deck, actual_score_goal));
|
|
||||||
case 5:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,5,4>(deck, actual_score_goal));
|
|
||||||
case 6:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,5,4>(deck, actual_score_goal));
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
switch(num_suits) {
|
|
||||||
case 3:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,6,3>(deck, actual_score_goal));
|
|
||||||
case 4:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,6,3>(deck, actual_score_goal));
|
|
||||||
case 5:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,6,3>(deck, actual_score_goal));
|
|
||||||
case 6:
|
|
||||||
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,6,3>(deck, actual_score_goal));
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Invalid number of players: " + std::to_string(num_players));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Hanabi::Game get_game(std::variant<int, std::string> game_spec, std::optional<uint8_t> score_goal){
|
Hanabi::Game get_game(std::variant<int, std::string> game_spec, std::optional<uint8_t> score_goal){
|
||||||
const std::optional<boost::json::object> game_json_opt = [&game_spec]() {
|
const std::optional<boost::json::object> game_json_opt = [&game_spec]() {
|
||||||
|
@ -118,7 +42,7 @@ namespace Download {
|
||||||
}
|
}
|
||||||
|
|
||||||
Hanabi::GameInfo game_info = Parsing::parse_game(game_json_opt.value());
|
Hanabi::GameInfo game_info = Parsing::parse_game(game_json_opt.value());
|
||||||
return {get_base_state(game_info.num_suits, game_info.num_players, game_info.deck, score_goal), game_info};
|
return {make_game_state(game_info.num_suits, game_info.num_players, game_info.deck, score_goal), game_info};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Download
|
} // namespace Download
|
||||||
|
|
83
src/make_state.cpp
Normal file
83
src/make_state.cpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#include "game_state.h"
|
||||||
|
#include "game_interface.h"
|
||||||
|
|
||||||
|
namespace Hanabi {
|
||||||
|
std::unique_ptr<Hanabi::HanabiStateIF> make_game_state(
|
||||||
|
std::size_t num_suits,
|
||||||
|
Hanabi::player_t num_players,
|
||||||
|
std::vector<Hanabi::Card> const &deck,
|
||||||
|
std::optional<uint8_t> score_goal)
|
||||||
|
{
|
||||||
|
uint8_t actual_score_goal = score_goal.value_or(5 * num_suits);
|
||||||
|
switch(num_players) {
|
||||||
|
case 2:
|
||||||
|
switch(num_suits) {
|
||||||
|
case 3:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,2,5>(deck, actual_score_goal));
|
||||||
|
case 4:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,2,5>(deck, actual_score_goal));
|
||||||
|
case 5:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,2,5>(deck, actual_score_goal));
|
||||||
|
case 6:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,2,5>(deck, actual_score_goal));
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
switch(num_suits) {
|
||||||
|
case 3:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,3,5>(deck, actual_score_goal));
|
||||||
|
case 4:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,3,5>(deck, actual_score_goal));
|
||||||
|
case 5:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,3,5>(deck, actual_score_goal));
|
||||||
|
case 6:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,3,5>(deck, actual_score_goal));
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
switch(num_suits) {
|
||||||
|
case 3:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,4,4>(deck, actual_score_goal));
|
||||||
|
case 4:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,4,4>(deck, actual_score_goal));
|
||||||
|
case 5:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,4,4>(deck, actual_score_goal));
|
||||||
|
case 6:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,4,4>(deck, actual_score_goal));
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
switch(num_suits) {
|
||||||
|
case 3:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,5,4>(deck, actual_score_goal));
|
||||||
|
case 4:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,5,4>(deck, actual_score_goal));
|
||||||
|
case 5:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,5,4>(deck, actual_score_goal));
|
||||||
|
case 6:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,5,4>(deck, actual_score_goal));
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
switch(num_suits) {
|
||||||
|
case 3:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<3,6,3>(deck, actual_score_goal));
|
||||||
|
case 4:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<4,6,3>(deck, actual_score_goal));
|
||||||
|
case 5:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<5,6,3>(deck, actual_score_goal));
|
||||||
|
case 6:
|
||||||
|
return std::unique_ptr<Hanabi::HanabiStateIF>(new Hanabi::HanabiState<6,6,3>(deck, actual_score_goal));
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid number of suits: " + std::to_string(num_suits));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid number of players: " + std::to_string(num_players));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue