more code cleanup: remove copy member from card
This commit is contained in:
parent
423be6c01b
commit
ffcdea4eb0
2 changed files with 26 additions and 75 deletions
43
game_state.h
43
game_state.h
|
@ -42,10 +42,8 @@ constexpr std::array<std::string, 6> suit_initials{"r", "y", "g", "b", "p", "t"}
|
||||||
struct Card {
|
struct Card {
|
||||||
suit_t suit;
|
suit_t suit;
|
||||||
rank_t rank;
|
rank_t rank;
|
||||||
uint8_t copy;
|
|
||||||
|
|
||||||
Card &operator++();
|
Card &operator++();
|
||||||
Card successor() const;
|
|
||||||
const Card operator++(int);
|
const Card operator++(int);
|
||||||
|
|
||||||
auto operator<=>(const Card &) const = default;
|
auto operator<=>(const Card &) const = default;
|
||||||
|
@ -56,16 +54,16 @@ std::ostream &operator<<(std::ostream &os, const Card &card) {
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Card r0 = {0, 0, 0};
|
constexpr Card r0 = {0, 0};
|
||||||
constexpr Card r1 = {0, 1, 0};
|
constexpr Card r1 = {0, 1};
|
||||||
constexpr Card r2 = {0, 2, 0};
|
constexpr Card r2 = {0, 2};
|
||||||
constexpr Card r3 = {0, 3, 0};
|
constexpr Card r3 = {0, 3};
|
||||||
constexpr Card r4 = {0, 4, 0};
|
constexpr Card r4 = {0, 4};
|
||||||
constexpr Card y0 = {1, 0, 0};
|
constexpr Card y0 = {1, 0};
|
||||||
constexpr Card y1 = {1, 1, 0};
|
constexpr Card y1 = {1, 1};
|
||||||
constexpr Card y2 = {1, 2, 0};
|
constexpr Card y2 = {1, 2};
|
||||||
constexpr Card y3 = {1, 3, 0};
|
constexpr Card y3 = {1, 3};
|
||||||
constexpr Card y4 = {1, 4, 0};
|
constexpr Card y4 = {1, 4};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To store:
|
* To store:
|
||||||
|
@ -87,24 +85,7 @@ struct CardMultiplicity {
|
||||||
auto operator<=>(const CardMultiplicity &) const = default;
|
auto operator<=>(const CardMultiplicity &) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::size_t num_suits, typename T, bool respect_card_duplicity>
|
template <std::size_t num_suits, typename T> struct CardArray {
|
||||||
struct CardArrayMember {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <std::size_t num_suits, typename T>
|
|
||||||
struct CardArrayMember<num_suits, T, true> {
|
|
||||||
auto operator<=>(const CardArrayMember &) const = default;
|
|
||||||
std::array<std::array<std::array<T , max_card_duplicity>, starting_card_rank>, num_suits> array {};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <std::size_t num_suits, typename T>
|
|
||||||
struct CardArrayMember<num_suits, T, false> {
|
|
||||||
auto operator<=>(const CardArrayMember &) const = default;
|
|
||||||
std::array<std::array<T, starting_card_rank>, num_suits> array {};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <std::size_t num_suits, typename T, bool respect_card_duplicity = true> struct CardArray {
|
|
||||||
|
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
CardArray() = default;
|
CardArray() = default;
|
||||||
|
@ -117,7 +98,7 @@ template <std::size_t num_suits, typename T, bool respect_card_duplicity = true>
|
||||||
auto operator<=>(const CardArray &) const = default;
|
auto operator<=>(const CardArray &) const = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CardArrayMember<num_suits, T, respect_card_duplicity> _vals;
|
std::array<std::array<T, starting_card_rank>, num_suits> _array {};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ActionType {
|
enum class ActionType {
|
||||||
|
|
|
@ -16,8 +16,6 @@ namespace Hanabi {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Card Card::successor() const { return {suit, static_cast<rank_t>(rank + 1)}; }
|
|
||||||
|
|
||||||
const Card Card::operator++(int) {
|
const Card Card::operator++(int) {
|
||||||
Card ret = *this;
|
Card ret = *this;
|
||||||
rank++;
|
rank++;
|
||||||
|
@ -33,35 +31,23 @@ namespace Hanabi {
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t num_suits, typename T, bool respect_card_duplicity>
|
template<std::size_t num_suits, typename T>
|
||||||
CardArray<num_suits, T, respect_card_duplicity>::CardArray(T default_val) {
|
CardArray<num_suits, T>::CardArray(T default_val) {
|
||||||
for(size_t suit = 0; suit < num_suits; suit++) {
|
for(size_t suit = 0; suit < num_suits; suit++) {
|
||||||
for (rank_t rank = 0; rank < starting_card_rank; rank++) {
|
for (rank_t rank = 0; rank < starting_card_rank; rank++) {
|
||||||
if constexpr (respect_card_duplicity) {
|
_array[suit][rank] = default_val;
|
||||||
std::ranges::fill(_vals.array[suit][rank], default_val);
|
|
||||||
} else {
|
|
||||||
_vals.array[suit][rank] = default_val;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t num_suits, typename T, bool respect_card_duplicity>
|
template<std::size_t num_suits, typename T>
|
||||||
const T& CardArray<num_suits, T, respect_card_duplicity>::operator[](const Card &card) const {
|
const T& CardArray<num_suits, T>::operator[](const Card &card) const {
|
||||||
if constexpr (respect_card_duplicity) {
|
return _array[card.suit][card.rank];
|
||||||
return _vals.array[card.suit][card.rank][card.copy];
|
|
||||||
} else {
|
|
||||||
return _vals.array[card.suit][card.rank];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t num_suits, typename T, bool respect_card_duplicity>
|
template<std::size_t num_suits, typename T>
|
||||||
T& CardArray<num_suits, T, respect_card_duplicity>::operator[](const Card &card) {
|
T& CardArray<num_suits, T>::operator[](const Card &card) {
|
||||||
if constexpr (respect_card_duplicity) {
|
return _array[card.suit][card.rank];
|
||||||
return _vals.array[card.suit][card.rank][card.copy];
|
|
||||||
} else {
|
|
||||||
return _vals.array[card.suit][card.rank];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t num_suits, player_t num_players, size_t hand_size>
|
template<size_t num_suits, player_t num_players, size_t hand_size>
|
||||||
|
@ -200,8 +186,6 @@ namespace Hanabi {
|
||||||
std::uint8_t HanabiState<num_suits, num_players, hand_size>::draw(uint8_t index) {
|
std::uint8_t HanabiState<num_suits, num_players, hand_size>::draw(uint8_t index) {
|
||||||
ASSERT(index < _hands[_turn].size());
|
ASSERT(index < _hands[_turn].size());
|
||||||
|
|
||||||
const Card& discarded = _hands[_turn][index];
|
|
||||||
|
|
||||||
// draw a new card if the draw pile is not empty
|
// draw a new card if the draw pile is not empty
|
||||||
if (!_draw_pile.empty()) {
|
if (!_draw_pile.empty()) {
|
||||||
--_weighted_draw_pile_size;
|
--_weighted_draw_pile_size;
|
||||||
|
@ -215,9 +199,7 @@ namespace Hanabi {
|
||||||
_draw_pile.back().multiplicity--;
|
_draw_pile.back().multiplicity--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Card& card_in_hand = _hands[_turn][index];
|
_hands[_turn][index] = draw.card;
|
||||||
card_in_hand = draw.card;
|
|
||||||
card_in_hand.copy = draw.multiplicity - 1;
|
|
||||||
|
|
||||||
if(_draw_pile.empty()) {
|
if(_draw_pile.empty()) {
|
||||||
// Note the +1, since we will immediately decrement this when moving to the next player
|
// Note the +1, since we will immediately decrement this when moving to the next player
|
||||||
|
@ -253,13 +235,13 @@ namespace Hanabi {
|
||||||
const Card trash = [this]() -> Card {
|
const Card trash = [this]() -> Card {
|
||||||
for(suit_t suit = 0; suit < num_suits; suit++) {
|
for(suit_t suit = 0; suit < num_suits; suit++) {
|
||||||
if(_stacks[suit] < starting_card_rank) {
|
if(_stacks[suit] < starting_card_rank) {
|
||||||
return {suit, starting_card_rank - 1, 0};
|
return {suit, starting_card_rank - 1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {0,0,0};
|
return {0,0};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
CardArray<num_suits, std::uint8_t, false> nums_in_draw_pile;
|
CardArray<num_suits, std::uint8_t> nums_in_draw_pile;
|
||||||
std::uint8_t num_trash_in_draw_pile = 0;
|
std::uint8_t num_trash_in_draw_pile = 0;
|
||||||
for(const auto [card, multiplicity] : _draw_pile) {
|
for(const auto [card, multiplicity] : _draw_pile) {
|
||||||
if (_stacks[card.suit] > card.rank) {
|
if (_stacks[card.suit] > card.rank) {
|
||||||
|
@ -272,25 +254,13 @@ namespace Hanabi {
|
||||||
_draw_pile.clear();
|
_draw_pile.clear();
|
||||||
for(suit_t suit = 0; suit < num_suits; suit++) {
|
for(suit_t suit = 0; suit < num_suits; suit++) {
|
||||||
for(rank_t rank = 0; rank < starting_card_rank; rank++) {
|
for(rank_t rank = 0; rank < starting_card_rank; rank++) {
|
||||||
Card card {suit, rank, 0};
|
Card card {suit, rank};
|
||||||
if (nums_in_draw_pile[card] > 0) {
|
if (nums_in_draw_pile[card] > 0) {
|
||||||
_draw_pile.push_back({card, nums_in_draw_pile[card]});
|
_draw_pile.push_back({card, nums_in_draw_pile[card]});
|
||||||
for (std::uint8_t copy = 0; copy < nums_in_draw_pile[card]; copy++) {
|
|
||||||
card.copy = copy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_draw_pile.push_back({trash, num_trash_in_draw_pile});
|
_draw_pile.push_back({trash, num_trash_in_draw_pile});
|
||||||
|
|
||||||
for(player_t player = 0; player < num_players; player++) {
|
|
||||||
for(Card& card : _hands[player]) {
|
|
||||||
if (_stacks[card.suit] > card.rank) {
|
|
||||||
card.copy = nums_in_draw_pile[card];
|
|
||||||
nums_in_draw_pile[card]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t num_suits, player_t num_players, std::size_t hand_size>
|
template<std::size_t num_suits, player_t num_players, std::size_t hand_size>
|
||||||
|
|
Loading…
Reference in a new issue