simplify function logic, expose more of interface
This commit is contained in:
parent
a6a8fb78af
commit
ec203198c0
2 changed files with 51 additions and 21 deletions
24
game_state.h
24
game_state.h
|
@ -159,10 +159,16 @@ public:
|
||||||
virtual void discard(hand_index_t index) = 0;
|
virtual void discard(hand_index_t index) = 0;
|
||||||
virtual void play(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 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_trash(const Card& card) const = 0;
|
||||||
[[nodiscard]] virtual bool is_playable(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 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 std::uint64_t enumerated_states() const = 0;
|
||||||
[[nodiscard]] virtual const std::unordered_map<unsigned long, probability_t>& position_tablebase() 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;
|
probability_t evaluate_state() final;
|
||||||
|
|
||||||
void clue() final;
|
void clue() final;
|
||||||
void play(hand_index_t index) final;
|
|
||||||
void discard(hand_index_t index) final;
|
void discard(hand_index_t index) final;
|
||||||
|
void play(hand_index_t index) final;
|
||||||
|
|
||||||
void revert_clue();
|
void revert() final;
|
||||||
void revert_play();
|
|
||||||
void revert_discard();
|
|
||||||
|
|
||||||
[[nodiscard]] hand_index_t find_card_in_hand(const Card& card) const 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_trash(const Card& card) const final;
|
||||||
[[nodiscard]] bool is_playable(const Card& card) const final;
|
[[nodiscard]] bool is_playable(const Card& card) const final;
|
||||||
[[nodiscard]] size_t draw_pile_size() 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]] std::uint64_t enumerated_states() const final;
|
||||||
[[nodiscard]] const std::unordered_map<unsigned long, probability_t>& position_tablebase() const final;
|
[[nodiscard]] const std::unordered_map<unsigned long, probability_t>& position_tablebase() const final;
|
||||||
|
@ -251,11 +256,16 @@ private:
|
||||||
bool initialized { false };
|
bool initialized { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool update_card_positions> unsigned long play_and_potentially_update(hand_index_t index);
|
unsigned long discard_and_potentially_update(hand_index_t index);
|
||||||
template<bool update_card_positions> 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_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);
|
void update_tablebase(unsigned long id, probability_t probability);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace Hanabi {
|
||||||
}
|
}
|
||||||
for (player_t player = 0; player < num_players; player++) {
|
for (player_t player = 0; player < num_players; player++) {
|
||||||
for (std::uint8_t index = 0; index < hand_size; index++) {
|
for (std::uint8_t index = 0; index < hand_size; index++) {
|
||||||
draw<false>(index);
|
draw(index);
|
||||||
}
|
}
|
||||||
incr_turn();
|
incr_turn();
|
||||||
}
|
}
|
||||||
|
@ -142,16 +142,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>
|
||||||
void HanabiState<num_suits, num_players, hand_size>::play(Hanabi::hand_index_t index) {
|
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<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) {
|
unsigned long HanabiState<num_suits, num_players, hand_size>::play_and_potentially_update(hand_index_t index) {
|
||||||
ASSERT(index < _hands[_turn].size());
|
ASSERT(index < _hands[_turn].size());
|
||||||
const Card played_card = _hands[_turn][index];
|
const Card played_card = _hands[_turn][index];
|
||||||
if (!is_playable(played_card)) {
|
if (!is_playable(played_card)) {
|
||||||
const unsigned long multiplicity = draw<false>(index);
|
const unsigned long multiplicity = draw(index);
|
||||||
incr_turn();
|
incr_turn();
|
||||||
return multiplicity;
|
return multiplicity;
|
||||||
}
|
}
|
||||||
|
@ -167,19 +166,18 @@ namespace Hanabi {
|
||||||
_num_clues++;
|
_num_clues++;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned long multiplicity = draw<update_card_positions>(index);
|
const unsigned long multiplicity = draw(index);
|
||||||
|
|
||||||
incr_turn();
|
incr_turn();
|
||||||
return multiplicity;
|
return multiplicity;
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
||||||
void HanabiState<num_suits, num_players, hand_size>::discard(std::uint8_t index) {
|
void HanabiState<num_suits, num_players, hand_size>::discard(hand_index_t index) {
|
||||||
discard_and_potentially_update<false>(index);
|
discard_and_potentially_update(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
||||||
template<bool update_card_positions>
|
|
||||||
unsigned long HanabiState<num_suits, num_players, hand_size>::discard_and_potentially_update(hand_index_t index) {
|
unsigned long HanabiState<num_suits, num_players, hand_size>::discard_and_potentially_update(hand_index_t index) {
|
||||||
ASSERT(index < _hands[_turn].size());
|
ASSERT(index < _hands[_turn].size());
|
||||||
ASSERT(_num_clues != max_num_clues);
|
ASSERT(_num_clues != max_num_clues);
|
||||||
|
@ -188,7 +186,7 @@ namespace Hanabi {
|
||||||
_num_clues++;
|
_num_clues++;
|
||||||
_pace--;
|
_pace--;
|
||||||
|
|
||||||
unsigned long multiplicity = draw<update_card_positions>(index);
|
unsigned long multiplicity = draw(index);
|
||||||
_actions_log.emplace(ActionType::discard, discarded_card, index);
|
_actions_log.emplace(ActionType::discard, discarded_card, index);
|
||||||
|
|
||||||
incr_turn();
|
incr_turn();
|
||||||
|
@ -229,12 +227,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>
|
||||||
template<bool update_card_positions>
|
|
||||||
unsigned long HanabiState<num_suits, num_players, hand_size>::draw(uint8_t index) {
|
unsigned long HanabiState<num_suits, num_players, hand_size>::draw(uint8_t index) {
|
||||||
ASSERT(index < _hands[_turn].size());
|
ASSERT(index < _hands[_turn].size());
|
||||||
|
|
||||||
// update card position of the card we are about to discard
|
// 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];
|
const Card discarded = _hands[_turn][index];
|
||||||
if (!discarded.initial_trash) {
|
if (!discarded.initial_trash) {
|
||||||
if (discarded.in_starting_hand) {
|
if (discarded.in_starting_hand) {
|
||||||
|
@ -261,7 +258,7 @@ namespace Hanabi {
|
||||||
_draw_pile.back().multiplicity--;
|
_draw_pile.back().multiplicity--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (update_card_positions) {
|
if (_relative_representation.initialized) {
|
||||||
// update card position of the drawn card
|
// update card position of the drawn card
|
||||||
if (!draw.card.initial_trash) {
|
if (!draw.card.initial_trash) {
|
||||||
ASSERT(draw.card.in_starting_hand == false);
|
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++) {
|
for (size_t i = 0; i < _relative_representation.num_useful_cards_in_starting_hands; i++) {
|
||||||
_relative_representation.card_positions_hands[i] = true;
|
_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>
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
|
@ -436,6 +434,23 @@ namespace Hanabi {
|
||||||
_num_clues++;
|
_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>
|
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() {
|
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) {
|
void HanabiState<num_suits, num_players, hand_size>::do_for_each_potential_draw(hand_index_t index, Function f) {
|
||||||
auto do_action = [this, index](){
|
auto do_action = [this, index](){
|
||||||
if constexpr (play) {
|
if constexpr (play) {
|
||||||
return play_and_potentially_update<true>(index);
|
return play_and_potentially_update(index);
|
||||||
} else {
|
} 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;
|
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>
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
void HanabiState<num_suits, num_players, hand_size>::update_tablebase(
|
void HanabiState<num_suits, num_players, hand_size>::update_tablebase(
|
||||||
unsigned long id,
|
unsigned long id,
|
||||||
|
|
Loading…
Reference in a new issue