consider playing trash at 8 clues
This commit is contained in:
parent
03abd08418
commit
863baf3acd
5 changed files with 34 additions and 5 deletions
|
@ -48,6 +48,8 @@ namespace Hanabi
|
|||
|
||||
[[nodiscard]] virtual clue_t num_clues() const = 0;
|
||||
|
||||
[[nodiscard]] virtual unsigned num_strikes() const = 0;
|
||||
|
||||
[[nodiscard]] virtual unsigned score() const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::vector<std::vector<Card>> hands() const = 0;
|
||||
|
|
|
@ -94,6 +94,8 @@ namespace Hanabi
|
|||
|
||||
[[nodiscard]] clue_t num_clues() const final;
|
||||
|
||||
[[nodiscard]] unsigned num_strikes() const final;
|
||||
|
||||
[[nodiscard]] unsigned score() const final;
|
||||
|
||||
[[nodiscard]] std::vector<std::vector<Card>> hands() const final;
|
||||
|
@ -233,6 +235,7 @@ namespace Hanabi
|
|||
|
||||
player_t _turn{};
|
||||
clue_t _num_clues{};
|
||||
unsigned _num_strikes{};
|
||||
std::uint8_t _weighted_draw_pile_size{};
|
||||
Stacks<num_suits> _stacks{};
|
||||
std::array<std::array<Card, hand_size>, num_players> _hands{};
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Hanabi
|
|||
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):
|
||||
_clues_gained_on_discard_or_stack_finished(num_clues_gained_on_discard_or_stack_finished)
|
||||
, _score_goal(score_goal), _turn(0), _num_clues(max_num_clues), _weighted_draw_pile_size(deck.size()), _stacks(), _hands(), _draw_pile()
|
||||
, _score_goal(score_goal), _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)
|
||||
, _actions_log(), _relative_representation(), _position_tablebase()
|
||||
, _enumerated_states(0)
|
||||
|
@ -214,6 +214,7 @@ namespace Hanabi
|
|||
_num_clues += _clues_gained_on_discard_or_stack_finished;
|
||||
}
|
||||
} else {
|
||||
_num_strikes++;
|
||||
_num_copies_left[played_card]--;
|
||||
}
|
||||
|
||||
|
@ -271,7 +272,7 @@ namespace Hanabi
|
|||
void HanabiState<num_suits, num_players, hand_size>::print(std::ostream & os) const
|
||||
{
|
||||
os << "Stacks: " << _stacks << " (score " << +_score << ")";
|
||||
os << ", clues: " << +_num_clues << ", turn: " << +_turn;
|
||||
os << ", clues: " << +_num_clues << ", strikes: " << +_num_strikes << ", turn: " << +_turn;
|
||||
if (_endgame_turns_left != no_endgame)
|
||||
{
|
||||
os << ", " << +_endgame_turns_left << " turns left";
|
||||
|
@ -644,6 +645,7 @@ namespace Hanabi
|
|||
} else {
|
||||
// If we misplayed, then we lost the card and have to regain it now
|
||||
_num_copies_left[last_action.discarded]++;
|
||||
_num_strikes--;
|
||||
}
|
||||
CHECK_DRAW_PILE_INTEGRITY;
|
||||
}
|
||||
|
@ -738,6 +740,12 @@ namespace Hanabi
|
|||
return _num_clues;
|
||||
}
|
||||
|
||||
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||
unsigned HanabiState<num_suits, num_players, hand_size>::num_strikes() const
|
||||
{
|
||||
return _num_strikes;
|
||||
}
|
||||
|
||||
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||
unsigned HanabiState<num_suits, num_players, hand_size>::score() const
|
||||
{
|
||||
|
@ -805,7 +813,7 @@ namespace Hanabi
|
|||
for (std::uint8_t index = 0; index < hand_size; index++)
|
||||
{
|
||||
Card card = hand[index];
|
||||
bool const consider_playing = is_playable(card) or (not is_critical(card) and not reasonable and (not is_trash(card) or not played_trash));
|
||||
bool const consider_playing = is_playable(card) or (_num_strikes < max_num_strikes and not is_critical(card) and (not reasonable or _num_clues == max_num_clues) and (not is_trash(card) or not played_trash));
|
||||
if (consider_playing)
|
||||
{
|
||||
if (is_trash(card))
|
||||
|
@ -1005,10 +1013,14 @@ namespace Hanabi
|
|||
const std::array<Card, hand_size> & hand = _hands[_turn];
|
||||
|
||||
// First, check for playables
|
||||
bool played_trash = false;
|
||||
for (std::uint8_t index = 0; index < hand_size; index++)
|
||||
{
|
||||
if (is_playable(hand[index]))
|
||||
if (is_playable(hand[index]) or (_num_clues == max_num_clues and _num_strikes < max_num_strikes and not is_critical(hand[index]) and (not is_trash(hand[index]) or not played_trash)))
|
||||
{
|
||||
if (is_trash(hand[index])) {
|
||||
played_trash = true;
|
||||
}
|
||||
probability_t const probability_play = check_play_or_discard(index, true);
|
||||
|
||||
best_probability = std::max(best_probability, probability_play);
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace Hanabi
|
|||
constexpr suit_t max_suit_index = 5;
|
||||
constexpr size_t max_card_duplicity = 3;
|
||||
const clue_t max_num_clues = 8;
|
||||
constexpr unsigned max_num_strikes = 2; /** Maximum number of allowed strikes */
|
||||
constexpr hand_index_t invalid_hand_idx = std::numeric_limits<hand_index_t>::max();
|
||||
|
||||
// We might want to change these at runtime to adapt to other variants.
|
||||
|
|
|
@ -397,7 +397,18 @@ namespace Hanabi
|
|||
|
||||
if (prompt.find("actions") == 0)
|
||||
{
|
||||
auto reasonable_actions = game.state->get_reasonable_actions();
|
||||
std::vector<std::pair<Hanabi::Action, std::optional<boost::rational<Hanabi::probability_base_type>>>> reasonable_actions = game.state->get_reasonable_actions();
|
||||
std::sort(reasonable_actions.begin(), reasonable_actions.end(),
|
||||
[](std::pair<Hanabi::Action, std::optional<probability_t>> const & left,
|
||||
std::pair<Hanabi::Action, std::optional<probability_t>> const & right){
|
||||
if (not left.second.has_value()) {
|
||||
return false;
|
||||
}
|
||||
if (not right.second.has_value()) {
|
||||
return true;
|
||||
}
|
||||
return left.second.value() < right.second.value();
|
||||
});
|
||||
int max_rational_digit_len = std::accumulate(
|
||||
reasonable_actions.begin(), reasonable_actions.end(), 0, [](
|
||||
int old, const std::pair<Action
|
||||
|
|
Loading…
Reference in a new issue