2023-11-15 22:58:09 +01:00
|
|
|
#ifndef DYNAMIC_PROGRAM_GAME_INTERFACE_H
|
|
|
|
#define DYNAMIC_PROGRAM_GAME_INTERFACE_H
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <iosfwd>
|
|
|
|
#include <vector>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <memory>
|
2023-11-15 23:07:39 +01:00
|
|
|
|
2023-11-15 22:58:09 +01:00
|
|
|
#include "hanabi_types.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Hanabi
|
|
|
|
{
|
|
|
|
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
[[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() = 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);
|
|
|
|
|
2023-11-15 23:23:21 +01:00
|
|
|
struct GameInfo
|
|
|
|
{
|
|
|
|
std::vector<Hanabi::Card> deck;
|
|
|
|
std::vector<Hanabi::Action> actions;
|
|
|
|
Hanabi::suit_t num_suits;
|
|
|
|
Hanabi::player_t num_players;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Game : private GameInfo {
|
|
|
|
public:
|
|
|
|
Game(std::unique_ptr<HanabiStateIF> state, GameInfo game_info);
|
2023-11-15 22:58:09 +01:00
|
|
|
|
|
|
|
[[nodiscard]] unsigned cur_turn() 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
|