diff --git a/download.h b/download.h index 8f2d123..83412b2 100644 --- a/download.h +++ b/download.h @@ -119,12 +119,12 @@ namespace Download { break; case Hanabi::ActionType::discard: index = game.find_card_in_hand(deck[actions[i].target]); - ASSERT(index != -1); + ASSERT(index != std::uint8_t(-1)); game.discard(index); break; case Hanabi::ActionType::play: index = game.find_card_in_hand(deck[actions[i].target]); - ASSERT(index != -1); + ASSERT(index != std::uint8_t(-1)); game.play(index); break; case Hanabi::ActionType::vote_terminate: diff --git a/game_state.h b/game_state.h index 5e894f5..424e09b 100644 --- a/game_state.h +++ b/game_state.h @@ -131,7 +131,6 @@ enum class ActionType { }; struct BacktrackAction { - ActionType type{}; // The card that was discarded or played Card discarded{}; // Index of card in hand that was discarded or played @@ -148,7 +147,7 @@ public: double backtrack(size_t depth); - BacktrackAction clue(); + void clue(); /** * Plays a card from current hand, drawing top card of draw pile and rotating draw pile @@ -162,7 +161,9 @@ public: void normalize_draw_and_positions(); - void revert(const BacktrackAction &action); + void revert_clue(); + void revert_play(const BacktrackAction &action); + void revert_discard(const BacktrackAction &action); uint8_t draw(uint8_t index); diff --git a/game_state.hpp b/game_state.hpp index f304679..1b05326 100644 --- a/game_state.hpp +++ b/game_state.hpp @@ -83,13 +83,11 @@ namespace Hanabi { } template - BacktrackAction HanabiState::clue() { + void HanabiState::clue() { ASSERT(_num_clues > 0); --_num_clues; incr_turn(); - - return BacktrackAction{ActionType::clue, {}, {}}; } template @@ -128,7 +126,7 @@ namespace Hanabi { --_stacks[card.suit]; _score++; - BacktrackAction ret{ActionType::play, _hands[_turn][index], index, 0}; + BacktrackAction ret{_hands[_turn][index], index, 0}; if (card.rank == 0) { // update clues if we played the last card of a stack @@ -149,7 +147,7 @@ namespace Hanabi { _num_clues++; _pace--; - BacktrackAction ret{ActionType::discard, _hands[_turn][index], index}; + BacktrackAction ret{_hands[_turn][index], index}; ret.multiplicity = draw(index); incr_turn(); @@ -303,30 +301,30 @@ namespace Hanabi { } template - void HanabiState::revert( - const BacktrackAction &action) { + void HanabiState::revert_play(const BacktrackAction& action) { decr_turn(); - switch (action.type) { - case ActionType::clue: - ASSERT(_num_clues < max_num_clues); - _num_clues++; - break; - case ActionType::discard: - ASSERT(_num_clues > 0); - _num_clues--; - _pace++; - revert_draw(action.index, action.discarded); - break; - case ActionType::play: - if (action.discarded.rank == 0) { - _num_clues--; - } - revert_draw(action.index, action.discarded); - _stacks[action.discarded.suit]++; - _score--; - default: - break; + if (action.discarded.rank == 0) { + _num_clues--; } + revert_draw(action.index, action.discarded); + _stacks[action.discarded.suit]++; + _score--; + } + + template + void HanabiState::revert_discard(const BacktrackAction& action) { + decr_turn(); + ASSERT(_num_clues > 0); + _num_clues--; + _pace++; + revert_draw(action.index, action.discarded); + } + + template + void HanabiState::revert_clue() { + decr_turn(); + ASSERT(_num_clues < max_num_clues); + _num_clues++; } #define UPDATE_PROBABILITY(new_probability) \ @@ -358,7 +356,7 @@ namespace Hanabi { auto copy = *this; BacktrackAction action = play(index); const double probability_for_this_play = backtrack(depth + 1); - revert(action); + revert_play(action); UPDATE_PROBABILITY(probability_for_this_play); } else { double sum_of_probabilities = 0; @@ -367,7 +365,7 @@ namespace Hanabi { BacktrackAction action = play(index); sum_of_probabilities += backtrack(depth + 1) * action.multiplicity; sum_of_mults += action.multiplicity; - revert(action); + revert_play(action); ASSERT(sum_of_mults <= _weighted_draw_pile_size); } ASSERT(sum_of_mults == _weighted_draw_pile_size); @@ -385,7 +383,7 @@ namespace Hanabi { if (_draw_pile.empty()) { BacktrackAction action = discard(index); const double probability_for_this_discard = backtrack(depth + 1); - revert(action); + revert_discard(action); UPDATE_PROBABILITY(probability_for_this_discard); } else { uint8_t sum_of_mults = 0; @@ -393,7 +391,7 @@ namespace Hanabi { BacktrackAction action = discard(index); sum_of_probabilities += backtrack(depth + 1) * action.multiplicity; sum_of_mults += action.multiplicity; - revert(action); + revert_discard(action); } ASSERT(sum_of_mults == _weighted_draw_pile_size); const double probability_discard = sum_of_probabilities / _weighted_draw_pile_size; @@ -408,9 +406,9 @@ namespace Hanabi { // Last option is to stall if(_num_clues > 0) { - BacktrackAction action = clue(); + clue(); const double probability_stall = backtrack(depth + 1); - revert(action); + revert_clue(); UPDATE_PROBABILITY(probability_stall); } diff --git a/main.cpp b/main.cpp index 33a7466..d350a12 100644 --- a/main.cpp +++ b/main.cpp @@ -30,7 +30,7 @@ void test_game() { auto a = state.play(4); std::cout << state; - state.revert(a); + state.revert_play(a); std::cout << state << std::endl; std::cout << state2 << std::endl; @@ -41,7 +41,7 @@ void test_game() { } void download(int turn) { - auto game = Download::get_game<6,5,4>(996518, turn); + auto game = Download::get_game<6,5,4>("996518", turn); std::cout << "Analysing state: " << game << std::endl; auto res = game.backtrack(1); std::cout << "Probability with optimal play: " << res << std::endl;