simplify function logic, expose more of interface

This commit is contained in:
Maximilian Keßler 2023-08-11 14:24:17 +02:00
parent a6a8fb78af
commit ec203198c0
Signed by: max
GPG key ID: BCC5A619923C0BA5
2 changed files with 51 additions and 21 deletions

View file

@ -159,10 +159,16 @@ public:
virtual void discard(hand_index_t index) = 0;
virtual void play(hand_index_t index) = 0;
/**
* May only be used if the relative state is already initialized
*/
virtual void revert() = 0;
[[nodiscard]] virtual hand_index_t find_card_in_hand(const Card& card) const = 0;
[[nodiscard]] virtual bool is_trash(const Card& card) const = 0;
[[nodiscard]] virtual bool is_playable(const Card& card) const = 0;
[[nodiscard]] virtual size_t draw_pile_size() const = 0;
[[nodiscard]] virtual bool is_relative_state_initialized() const = 0;
[[nodiscard]] virtual std::uint64_t enumerated_states() const = 0;
[[nodiscard]] virtual const std::unordered_map<unsigned long, probability_t>& position_tablebase() const = 0;
@ -186,17 +192,16 @@ public:
probability_t evaluate_state() final;
void clue() final;
void play(hand_index_t index) final;
void discard(hand_index_t index) final;
void play(hand_index_t index) final;
void revert_clue();
void revert_play();
void revert_discard();
void revert() final;
[[nodiscard]] hand_index_t find_card_in_hand(const Card& card) const final;
[[nodiscard]] bool is_trash(const Card& card) const final;
[[nodiscard]] bool is_playable(const Card& card) const final;
[[nodiscard]] size_t draw_pile_size() const final;
[[nodiscard]] bool is_relative_state_initialized() const final;
[[nodiscard]] std::uint64_t enumerated_states() const final;
[[nodiscard]] const std::unordered_map<unsigned long, probability_t>& position_tablebase() const final;
@ -251,11 +256,16 @@ private:
bool initialized { false };
};
template<bool update_card_positions> unsigned long play_and_potentially_update(hand_index_t index);
template<bool update_card_positions> unsigned long discard_and_potentially_update(hand_index_t index);
unsigned long discard_and_potentially_update(hand_index_t index);
unsigned long play_and_potentially_update(hand_index_t index);
unsigned long draw(hand_index_t index);
template<bool update_card_positions> unsigned long draw(hand_index_t index);
void revert_draw(hand_index_t index, Card discarded_card);
void revert_clue();
void revert_discard();
void revert_play();
void update_tablebase(unsigned long id, probability_t probability);

View file

@ -93,7 +93,7 @@ namespace Hanabi {
}
for (player_t player = 0; player < num_players; player++) {
for (std::uint8_t index = 0; index < hand_size; index++) {
draw<false>(index);
draw(index);
}
incr_turn();
}
@ -142,16 +142,15 @@ namespace Hanabi {
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
void HanabiState<num_suits, num_players, hand_size>::play(Hanabi::hand_index_t index) {
play_and_potentially_update<false>(index);
play_and_potentially_update(index);
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
template<bool update_card_positions>
unsigned long HanabiState<num_suits, num_players, hand_size>::play_and_potentially_update(hand_index_t index) {
ASSERT(index < _hands[_turn].size());
const Card played_card = _hands[_turn][index];
if (!is_playable(played_card)) {
const unsigned long multiplicity = draw<false>(index);
const unsigned long multiplicity = draw(index);
incr_turn();
return multiplicity;
}
@ -167,19 +166,18 @@ namespace Hanabi {
_num_clues++;
}
const unsigned long multiplicity = draw<update_card_positions>(index);
const unsigned long multiplicity = draw(index);
incr_turn();
return multiplicity;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
void HanabiState<num_suits, num_players, hand_size>::discard(std::uint8_t index) {
discard_and_potentially_update<false>(index);
void HanabiState<num_suits, num_players, hand_size>::discard(hand_index_t index) {
discard_and_potentially_update(index);
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
template<bool update_card_positions>
unsigned long HanabiState<num_suits, num_players, hand_size>::discard_and_potentially_update(hand_index_t index) {
ASSERT(index < _hands[_turn].size());
ASSERT(_num_clues != max_num_clues);
@ -188,7 +186,7 @@ namespace Hanabi {
_num_clues++;
_pace--;
unsigned long multiplicity = draw<update_card_positions>(index);
unsigned long multiplicity = draw(index);
_actions_log.emplace(ActionType::discard, discarded_card, index);
incr_turn();
@ -229,12 +227,11 @@ namespace Hanabi {
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
template<bool update_card_positions>
unsigned long HanabiState<num_suits, num_players, hand_size>::draw(uint8_t index) {
ASSERT(index < _hands[_turn].size());
// update card position of the card we are about to discard
if constexpr (update_card_positions) {
if (_relative_representation.initialized) {
const Card discarded = _hands[_turn][index];
if (!discarded.initial_trash) {
if (discarded.in_starting_hand) {
@ -261,7 +258,7 @@ namespace Hanabi {
_draw_pile.back().multiplicity--;
}
if constexpr (update_card_positions) {
if (_relative_representation.initialized) {
// update card position of the drawn card
if (!draw.card.initial_trash) {
ASSERT(draw.card.in_starting_hand == false);
@ -386,6 +383,7 @@ namespace Hanabi {
for (size_t i = 0; i < _relative_representation.num_useful_cards_in_starting_hands; i++) {
_relative_representation.card_positions_hands[i] = true;
}
_relative_representation.initialized = true;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
@ -436,6 +434,23 @@ namespace Hanabi {
_num_clues++;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
void HanabiState<num_suits, num_players, hand_size>::revert() {
switch(_actions_log.top().action_type) {
case ActionType::clue:
revert_clue();
break;
case ActionType::discard:
revert_discard();
break;
case ActionType::play:
revert_play();
break;
default:
return;
}
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
probability_t HanabiState<num_suits, num_players, hand_size>::evaluate_state() {
@ -524,9 +539,9 @@ namespace Hanabi {
void HanabiState<num_suits, num_players, hand_size>::do_for_each_potential_draw(hand_index_t index, Function f) {
auto do_action = [this, index](){
if constexpr (play) {
return play_and_potentially_update<true>(index);
return play_and_potentially_update(index);
} else {
return discard_and_potentially_update<true>(index);
return discard_and_potentially_update(index);
}
};
@ -616,6 +631,11 @@ namespace Hanabi {
return _weighted_draw_pile_size;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
bool HanabiState<num_suits, num_players, hand_size>::is_relative_state_initialized() const {
return _relative_representation.initialized;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
void HanabiState<num_suits, num_players, hand_size>::update_tablebase(
unsigned long id,