bugfix: card cycling on reverting only used internally
This ensures that when doing a regular revert, we revert to exactly the same state (i.e. also identical ordering of draw pile by default) and only rotate the draw pile in case we ensure internally that we iterate over all possible draws so that the ordering is restored in the end.
This commit is contained in:
parent
b6a2dfb855
commit
5b0834bc22
2 changed files with 29 additions and 16 deletions
|
@ -368,10 +368,10 @@ private:
|
||||||
|
|
||||||
unsigned draw(hand_index_t index);
|
unsigned 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, bool cycle = false);
|
||||||
void revert_clue();
|
void revert_clue();
|
||||||
void revert_discard();
|
void revert_discard(bool cycle = false);
|
||||||
void revert_play();
|
void revert_play(bool cycle = false);
|
||||||
|
|
||||||
|
|
||||||
void update_tablebase(unsigned long id, probability_t probability);
|
void update_tablebase(unsigned long id, probability_t probability);
|
||||||
|
|
|
@ -362,18 +362,29 @@ 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>::revert_draw(std::uint8_t index, Card discarded_card) {
|
void HanabiState<num_suits, num_players, hand_size>::revert_draw(std::uint8_t index, Card discarded_card, bool cycle) {
|
||||||
if (_endgame_turns_left == num_players + 1 || _endgame_turns_left == no_endgame) {
|
if (_endgame_turns_left == num_players + 1 || _endgame_turns_left == no_endgame) {
|
||||||
// Put the card that is currently in hand back into the draw pile
|
// Put the card that is currently in hand back into the draw pile
|
||||||
ASSERT(index < _hands[_turn].size());
|
ASSERT(index < _hands[_turn].size());
|
||||||
const Card &drawn = _hands[_turn][index];
|
const Card &drawn = _hands[_turn][index];
|
||||||
|
|
||||||
// put discarded_card back into draw pile (at the back)
|
if (cycle)
|
||||||
if (!_draw_pile.empty() and _draw_pile.back().card.suit == drawn.suit and
|
{
|
||||||
_draw_pile.back().card.rank == drawn.rank) {
|
// put discarded_card back into draw pile (at the back)
|
||||||
_draw_pile.back().multiplicity++;
|
if (!_draw_pile.empty() and _draw_pile.back().card.suit == drawn.suit and
|
||||||
} else {
|
_draw_pile.back().card.rank == drawn.rank) {
|
||||||
_draw_pile.push_back({drawn, 1});
|
_draw_pile.back().multiplicity++;
|
||||||
|
} else {
|
||||||
|
_draw_pile.push_back({drawn, 1});
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (!_draw_pile.empty() and _draw_pile.front().card.suit == drawn.suit and
|
||||||
|
_draw_pile.front().card.rank == drawn.rank) {
|
||||||
|
_draw_pile.front().multiplicity++;
|
||||||
|
} else {
|
||||||
|
_draw_pile.push_front({drawn, 1});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_relative_representation.initialized && !drawn.initial_trash) {
|
if (_relative_representation.initialized && !drawn.initial_trash) {
|
||||||
|
@ -473,7 +484,7 @@ 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
|
void
|
||||||
HanabiState<num_suits, num_players, hand_size>::revert_play() {
|
HanabiState<num_suits, num_players, hand_size>::revert_play(bool cycle) {
|
||||||
check_draw_pile_integrity();
|
check_draw_pile_integrity();
|
||||||
const BacktrackAction last_action = _actions_log.top();
|
const BacktrackAction last_action = _actions_log.top();
|
||||||
_actions_log.pop();
|
_actions_log.pop();
|
||||||
|
@ -484,7 +495,7 @@ namespace Hanabi {
|
||||||
if (last_action.discarded.rank == 0 and not last_action.was_on_8_clues) {
|
if (last_action.discarded.rank == 0 and not last_action.was_on_8_clues) {
|
||||||
_num_clues--;
|
_num_clues--;
|
||||||
}
|
}
|
||||||
revert_draw(last_action.index, last_action.discarded);
|
revert_draw(last_action.index, last_action.discarded, cycle);
|
||||||
if(_stacks[last_action.discarded.suit] == last_action.discarded.rank) {
|
if(_stacks[last_action.discarded.suit] == last_action.discarded.rank) {
|
||||||
_stacks[last_action.discarded.suit]++;
|
_stacks[last_action.discarded.suit]++;
|
||||||
}
|
}
|
||||||
|
@ -493,7 +504,7 @@ 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>::revert_discard() {
|
void HanabiState<num_suits, num_players, hand_size>::revert_discard(bool cycle) {
|
||||||
check_draw_pile_integrity();
|
check_draw_pile_integrity();
|
||||||
const BacktrackAction last_action = _actions_log.top();
|
const BacktrackAction last_action = _actions_log.top();
|
||||||
_actions_log.pop();
|
_actions_log.pop();
|
||||||
|
@ -506,7 +517,7 @@ namespace Hanabi {
|
||||||
_num_clues--;
|
_num_clues--;
|
||||||
_pace++;
|
_pace++;
|
||||||
|
|
||||||
revert_draw(last_action.index, last_action.discarded);
|
revert_draw(last_action.index, last_action.discarded, cycle);
|
||||||
check_draw_pile_integrity();
|
check_draw_pile_integrity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,6 +811,7 @@ 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<class Function>
|
template<class Function>
|
||||||
void HanabiState<num_suits, num_players, hand_size>::do_for_each_potential_draw(hand_index_t index, bool play, Function f) {
|
void HanabiState<num_suits, num_players, hand_size>::do_for_each_potential_draw(hand_index_t index, bool play, Function f) {
|
||||||
|
auto copy = _draw_pile;
|
||||||
auto do_action = [this, index, play](){
|
auto do_action = [this, index, play](){
|
||||||
if (play) {
|
if (play) {
|
||||||
return play_and_potentially_update(index);
|
return play_and_potentially_update(index);
|
||||||
|
@ -810,9 +822,9 @@ namespace Hanabi {
|
||||||
|
|
||||||
auto revert_action = [this, play](){
|
auto revert_action = [this, play](){
|
||||||
if (play) {
|
if (play) {
|
||||||
revert_play();
|
revert_play(true);
|
||||||
} else {
|
} else {
|
||||||
revert_discard();
|
revert_discard(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -831,6 +843,7 @@ namespace Hanabi {
|
||||||
}
|
}
|
||||||
ASSERT(sum_of_multiplicities == _weighted_draw_pile_size);
|
ASSERT(sum_of_multiplicities == _weighted_draw_pile_size);
|
||||||
}
|
}
|
||||||
|
ASSERT(_draw_pile == copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
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