Introduce option for HanabiState to save memory
This commit is contained in:
parent
27922de8e8
commit
bfc731ae36
2 changed files with 29 additions and 9 deletions
|
@ -62,6 +62,20 @@ namespace Hanabi
|
||||||
std::array<inner_array_t, num_suits> _array{};
|
std::array<inner_array_t, num_suits> _array{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct HanabiStateConfig
|
||||||
|
{
|
||||||
|
/** What score to consider as a win. If left empty, automatically replaced by max score on construction. */
|
||||||
|
std::optional<uint8_t> score_goal;
|
||||||
|
/** The number of clues gained when a stack is finished or a card is discarded. Usually 1, 1/2 in clue starved. */
|
||||||
|
clue_t num_clues_gained_on_discard_or_stack_finished {1};
|
||||||
|
/**
|
||||||
|
* 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};
|
||||||
|
};
|
||||||
|
|
||||||
// A game mimics a game state together with a list of actions and allows to traverse the game
|
// A game mimics a game state together with a list of actions and allows to traverse the game
|
||||||
// history by making and reverting the stored actions.
|
// history by making and reverting the stored actions.
|
||||||
|
@ -71,7 +85,7 @@ namespace Hanabi
|
||||||
public:
|
public:
|
||||||
HanabiState() = default;
|
HanabiState() = default;
|
||||||
|
|
||||||
explicit HanabiState(const std::vector<Card> & deck, uint8_t score_goal = 5 * num_suits, clue_t num_clues_gained_on_discard_or_stack_finished = 1);
|
explicit HanabiState(const std::vector<Card> & deck, HanabiStateConfig config = HanabiStateConfig());
|
||||||
|
|
||||||
void give_clue() final;
|
void give_clue() final;
|
||||||
|
|
||||||
|
@ -263,10 +277,10 @@ namespace Hanabi
|
||||||
RelativeRepresentationData _relative_representation;
|
RelativeRepresentationData _relative_representation;
|
||||||
|
|
||||||
// Lookup table for states. Uses the ids calculated using the relative representation
|
// Lookup table for states. Uses the ids calculated using the relative representation
|
||||||
|
bool const _save_memory;
|
||||||
map_type<unsigned long, probability_t> _position_tablebase;
|
map_type<unsigned long, probability_t> _position_tablebase;
|
||||||
|
|
||||||
std::uint64_t _enumerated_states{};
|
std::uint64_t _enumerated_states{};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t num_suits, player_t num_players, std::size_t hand_size>
|
template<std::size_t num_suits, player_t num_players, std::size_t hand_size>
|
||||||
|
|
|
@ -75,11 +75,11 @@ namespace Hanabi
|
||||||
}
|
}
|
||||||
|
|
||||||
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
HanabiState<num_suits, num_players, hand_size>::HanabiState(const std::vector<Card> & deck, uint8_t score_goal, clue_t num_clues_gained_on_discard_or_stack_finished):
|
HanabiState<num_suits, num_players, hand_size>::HanabiState(const std::vector<Card> & deck, HanabiStateConfig config):
|
||||||
_clues_gained_on_discard_or_stack_finished(num_clues_gained_on_discard_or_stack_finished)
|
_clues_gained_on_discard_or_stack_finished(config.num_clues_gained_on_discard_or_stack_finished)
|
||||||
, _score_goal(score_goal), _turn(0), _num_clues(max_num_clues), _num_strikes(0), _weighted_draw_pile_size(deck.size()), _stacks(), _hands(), _draw_pile()
|
, _score_goal(config.score_goal.value_or(num_suits * 5)), _turn(0), _num_clues(max_num_clues), _num_strikes(0), _weighted_draw_pile_size(deck.size()), _stacks(), _hands(), _draw_pile()
|
||||||
, _endgame_turns_left(no_endgame), _pace(deck.size() - score_goal - num_players * (hand_size - 1)), _score(0)
|
, _endgame_turns_left(no_endgame), _pace(deck.size() - _score_goal - num_players * (hand_size - 1)), _score(0)
|
||||||
, _actions_log(), _relative_representation(), _position_tablebase()
|
, _actions_log(), _relative_representation(), _save_memory(config.save_memory), _position_tablebase()
|
||||||
, _enumerated_states(0)
|
, _enumerated_states(0)
|
||||||
{
|
{
|
||||||
std::fill(_stacks.begin(), _stacks.end(), starting_card_rank);
|
std::fill(_stacks.begin(), _stacks.end(), starting_card_rank);
|
||||||
|
@ -984,9 +984,15 @@ namespace Hanabi
|
||||||
|
|
||||||
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
bool HanabiState<num_suits, num_players, hand_size>::save_state_to_map()
|
bool HanabiState<num_suits, num_players, hand_size>::save_state_to_map()
|
||||||
|
{
|
||||||
|
if (_save_memory)
|
||||||
|
{
|
||||||
|
return _weighted_draw_pile_size % 2 == 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
return _draw_pile.size() != 2;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
|
|
Loading…
Reference in a new issue