#ifndef DYNAMIC_PROGRAM_GAME_INTERFACE_H #define DYNAMIC_PROGRAM_GAME_INTERFACE_H #include #include #include #include #include #include "hanabi_types.hpp" namespace Hanabi { /** * A card together with an associated multiplicity */ struct CardMultiplicity { Card card; unsigned multiplicity; bool operator==(const CardMultiplicity &) const = default; }; class HanabiStateIF { public: virtual void give_clue() = 0; virtual void discard(hand_index_t index) = 0; virtual void play(hand_index_t index) = 0; virtual void rotate_next_draw(const Card & card) = 0; [[nodiscard]] virtual ActionType last_action_type() const = 0; virtual void revert() = 0; virtual void modify_clues(clue_t change) = 0; virtual void set_clues(clue_t clues) = 0; [[nodiscard]] virtual player_t turn() const = 0; [[nodiscard]] virtual clue_t num_clues() const = 0; [[nodiscard]] virtual unsigned score() const = 0; [[nodiscard]] virtual std::vector> hands() const = 0; [[nodiscard]] virtual std::vector cur_hand() const = 0; [[nodiscard]] virtual size_t draw_pile_size() const = 0; [[nodiscard]] virtual bool is_trash(const Card & card) const = 0; /** Returns whether the card is critical, assuming it is not trash already */ [[nodiscard]] virtual bool is_critical(const Card & card) const = 0; [[nodiscard]] virtual bool is_playable(const Card & card) const = 0; [[nodiscard]] virtual bool is_relative_state_initialized() const = 0; [[nodiscard]] virtual hand_index_t find_card_in_hand(const Card & card) const = 0; [[nodiscard]] virtual std::uint64_t enumerated_states() const = 0; [[nodiscard]] virtual const std::unordered_map & position_tablebase() const = 0; virtual void init_backtracking_information() = 0; virtual probability_t evaluate_state() = 0; [[nodiscard]] virtual std::optional lookup() const = 0; [[nodiscard]] virtual std::uint64_t unique_id() const = 0; [[nodiscard]] virtual std::pair, std::vector> dump_unique_id_parts() const = 0; virtual std::vector>> get_reasonable_actions(bool evaluate_all = false) = 0; virtual std::vector>> possible_next_states(hand_index_t index, bool play) = 0; virtual ~HanabiStateIF() = default; protected: virtual void print(std::ostream & os) const = 0; friend std::ostream & operator<<(std::ostream &, HanabiStateIF const &); }; std::ostream & operator<<(std::ostream & os, HanabiStateIF const & hanabi_state); struct GameInfo { std::vector deck; std::vector actions; Hanabi::suit_t num_suits; Hanabi::player_t num_players; clue_t num_clues_gained_per_discard_or_stack_finished; }; struct Game : private GameInfo { public: Game(std::unique_ptr state, GameInfo game_info); [[nodiscard]] unsigned cur_turn() const; [[nodiscard]] unsigned num_turns() const; void make_turn(); void revert_turn(); bool goto_draw_pile_size(size_t draw_pile_break); bool goto_turn(size_t turn); [[nodiscard]] bool holds_state() const; std::unique_ptr state; unsigned next_action; }; } #endif //DYNAMIC_PROGRAM_GAME_INTERFACE_H