Endgame-Analyzer/include/game_interface.h

131 lines
3.5 KiB
C++

#ifndef DYNAMIC_PROGRAM_GAME_INTERFACE_H
#define DYNAMIC_PROGRAM_GAME_INTERFACE_H
#include <cstddef>
#include <iosfwd>
#include <vector>
#include <unordered_map>
#include <memory>
#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<std::vector<Card>> hands() const = 0;
[[nodiscard]] virtual std::vector<Card> 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<unsigned long, probability_t> & position_tablebase() const = 0;
virtual void init_backtracking_information() = 0;
virtual probability_t evaluate_state() = 0;
[[nodiscard]] virtual std::optional<probability_t> lookup() const = 0;
[[nodiscard]] virtual std::uint64_t unique_id() const = 0;
[[nodiscard]] virtual std::pair<std::vector<std::uint64_t>, std::vector<Card>> dump_unique_id_parts() const = 0;
virtual std::vector<std::pair<Action, std::optional<probability_t>>> get_reasonable_actions(bool evaluate_all = false, bool reasonable = true) = 0;
virtual std::vector<std::pair<CardMultiplicity, std::optional<probability_t>>>
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<Hanabi::Card> deck;
std::vector<Hanabi::Action> 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<HanabiStateIF> 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<HanabiStateIF> state;
unsigned next_action;
};
}
#endif //DYNAMIC_PROGRAM_GAME_INTERFACE_H