From 452c028f72cf4994959f577089c95c930613943f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ke=C3=9Fler?= Date: Sat, 5 Aug 2023 12:19:34 +0200 Subject: [PATCH] proper constructor for hanabi state --- game_state.h | 77 +++++++++++++++++++++++++------------------------- game_state.hpp | 49 ++++++++++++++++++++++++++------ main.cpp | 2 +- 3 files changed, 79 insertions(+), 49 deletions(-) diff --git a/game_state.h b/game_state.h index 388517e..7e3fc01 100644 --- a/game_state.h +++ b/game_state.h @@ -90,17 +90,16 @@ struct CardMultiplicity { template struct CardPositions { - const player_t &operator[](const Card &card) const; + CardPositions(); - player_t &operator[](const Card &card); + const player_t &operator[](const Card &card) const; - auto operator<=>(const CardPositions &) const = default; + player_t &operator[](const Card &card); + + auto operator<=>(const CardPositions &) const = default; private: - std::array< - std::array, starting_card_rank>, - num_suits> - _card_positions; + std::array, starting_card_rank>, num_suits> _card_positions; }; enum class ActionType { discard, clue, play }; @@ -111,48 +110,48 @@ struct Action { std::uint8_t index{}; }; -template +template class HanabiState { public: - Action clue(); - /** - * Plays a card from current hand, drawing top card of draw pile and rotating draw pile - * @param index of card in hand to be played - */ - Action play(std::uint8_t index); + HanabiState() = default; + explicit HanabiState(const std::vector& deck); - Action discard(std::uint8_t index); + Action clue(); - void revert(const Action &action); + /** + * Plays a card from current hand, drawing top card of draw pile and rotating draw pile + * @param index of card in hand to be played + */ + Action play(std::uint8_t index); - void draw(std::uint8_t index); - void revert_draw(std::uint8_t index, Card card); - void incr_turn(); - void decr_turn(); + Action discard(std::uint8_t index); - player_t _turn{}; - clue_t _num_clues{}; - std::uint8_t _draw_pile_size{}; - Stacks _stacks{}; - std::array, num_players> - _hands{}; - CardPositions _card_positions{}; - std::list _draw_pile{}; + void revert(const Action &action); - // further statistics that we might want to keep track of - uint8_t _pace{}; + void draw(std::uint8_t index); - auto operator<=>(const HanabiState &) const = default; + void revert_draw(std::uint8_t index, Card card); + + void incr_turn(); + + void decr_turn(); + + player_t _turn{}; + clue_t _num_clues{}; + std::uint8_t _draw_pile_size{}; + Stacks _stacks{}; + std::array, num_players> _hands{}; + CardPositions _card_positions{}; + std::list _draw_pile{}; + + // further statistics that we might want to keep track of + uint8_t _pace{}; + + auto operator<=>(const HanabiState &) const = default; }; -template -std::ostream & -operator<<(std::ostream &os, - HanabiState - hanabi_state); - +template +std::ostream & operator<<(std::ostream &os, HanabiState hanabi_state); template class HanabiState<5, 3, 4, 20>; diff --git a/game_state.hpp b/game_state.hpp index f4f66d2..019fc77 100644 --- a/game_state.hpp +++ b/game_state.hpp @@ -26,6 +26,15 @@ namespace Hanabi { return os; } + template + CardPositions::CardPositions() { + for(size_t suit = 0; suit < num_suits; suit++) { + for(rank_t rank = 0; rank < starting_card_rank; rank++) { + std::ranges::fill(_card_positions[suit][rank], draw_pile); + } + } + } + template const player_t &CardPositions::operator[](const Card &card) const { return _card_positions[card.suit][card.rank][card.copy]; @@ -36,7 +45,29 @@ namespace Hanabi { return _card_positions[card.suit][card.rank][card.copy]; }; - template + template + HanabiState::HanabiState(const std::vector &deck): + _turn(0), + _num_clues(max_num_clues), + _draw_pile_size(deck.size() - num_players * hand_size), + _stacks(), + _hands(), + _card_positions(), + _draw_pile() { + std::ranges::fill(_stacks, starting_card_rank); + for(const Card& card: deck) { + _draw_pile.push_back({card, 1}); + } + for(player_t player = 0; player < num_players; player++) { + for(std::uint8_t index = 0; index < hand_size; index++) { + draw(index); + } + incr_turn(); + } + assert(_turn == 0); + } + + template Action HanabiState::clue() { assert(_num_clues > 0); --_num_clues; @@ -46,19 +77,19 @@ namespace Hanabi { return Action{ActionType::clue, {}, {}}; } - template + template void HanabiState::incr_turn() { _turn = (_turn + 1) % num_players; } - template + template void HanabiState::decr_turn() { _turn = (_turn + num_players - 1) % num_players; } - template + template Action HanabiState::play( std::uint8_t index) { assert(index < _hands[_turn].size()); @@ -80,7 +111,7 @@ namespace Hanabi { return ret; } - template + template Action HanabiState::discard( std::uint8_t index) { assert(index < _hands[_turn].size()); @@ -96,7 +127,7 @@ namespace Hanabi { return ret; } - template + template std::ostream &operator<<(std::ostream &os, const HanabiState hanabi_state) { os << "Stacks: " << hanabi_state._stacks << std::endl; os << "Draw pile: "; @@ -117,7 +148,7 @@ namespace Hanabi { return os; } - template + template void HanabiState::draw(std::uint8_t index) { assert(index < _hands[_turn].size()); @@ -138,7 +169,7 @@ namespace Hanabi { } } - template + template void HanabiState::revert_draw(std::uint8_t index, Card card) { assert(index < _hands[_turn].size()); @@ -156,7 +187,7 @@ namespace Hanabi { _draw_pile_size++; } - template + template void HanabiState::revert( const Action &action) { decr_turn(); diff --git a/main.cpp b/main.cpp index 9654795..f9a8c83 100644 --- a/main.cpp +++ b/main.cpp @@ -21,8 +21,8 @@ void test_game() { state._draw_pile.push_back({r41, 1}); state._hands[0] = {y0, y1, y2, r0, r1}; state._hands[1] = {r1, r1, y1, r3, r2}; + state._card_positions[r1] = 0; state._draw_pile_size = 1; - state._card_positions[r41] = draw_pile; auto state2 = state;