#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
#include <system/thread_data.hpp>
#include <system/util/utilities.hpp>
#include <trans_table/trans_table.hpp>
enum class TTKind { Small, Large };
struct SolverConfig
{
TTKind tt_kind_ = TTKind::Large;
int tt_mem_default_mb_ = 0;
int tt_mem_maximum_mb_ = 0;
};
class SolverContext
{
public:
explicit SolverContext(std::shared_ptr<ThreadData> thread, SolverConfig cfg = {})
: thr_(std::move(thread)), cfg_(cfg)
{
search_.set_thread(thr_);
search_.set_owner(this);
}
explicit SolverContext(SolverConfig cfg = {});
~SolverContext();
auto thread() const -> std::shared_ptr<ThreadData>
{
return thr_;
}
auto config() const -> const SolverConfig&
{
return cfg_;
}
class UtilitiesContext
{
public:
explicit UtilitiesContext(::dds::Utilities* util)
: util_(util)
{
}
auto util() -> ::dds::Utilities&
{
return *util_;
}
auto util() const -> const ::dds::Utilities&
{
return *util_;
}
auto log_append(const std::string& s) -> void
{
util_->log_append(s);
}
auto log_buffer() const -> const std::vector<std::string>&
{
return util_->log_buffer();
}
auto log_clear() -> void
{
util_->log_clear();
}
private:
::dds::Utilities* util_ = nullptr;
};
auto utilities() -> UtilitiesContext
{
return UtilitiesContext(&utils_);
}
auto utilities() const -> UtilitiesContext
{
return UtilitiesContext(const_cast<dds::Utilities*>(&utils_));
}
auto trans_table() const -> TransTable*;
auto maybe_trans_table() const -> TransTable*;
auto dispose_trans_table() const -> void;
auto reset_for_solve() const -> void;
auto reset_best_moves_lite() const -> void;
auto clear_tt() const -> void;
auto resize_tt(int defMB, int maxMB) const -> void;
auto configure_tt(TTKind kind, int defMB, int maxMB) -> void;
class SearchContext
{
public:
SearchContext() = default;
explicit SearchContext(std::shared_ptr<ThreadData> thr)
: thr_(std::move(thr))
{
}
auto trans_table() -> TransTable*;
auto maybe_trans_table() const -> TransTable*;
auto dispose_trans_table() -> void;
auto analysis_flag() -> bool&;
auto analysis_flag() const -> bool;
auto lowest_win(int depth, int suit) -> unsigned short&;
auto lowest_win(int depth, int suit) const -> const unsigned short&;
auto best_move(int depth) -> MoveType&;
auto best_move(int depth) const -> const MoveType&;
auto best_move_tt(int depth) -> MoveType&;
auto best_move_tt(int depth) const -> const MoveType&;
auto winners(int trickIndex) -> WinnersType&;
auto winners(int trickIndex) const -> const WinnersType&;
auto node_type_store(int hand) -> int&;
auto node_type_store(int hand) const -> const int&;
auto forbidden_moves() -> MoveType*;
auto forbidden_moves() const -> const MoveType*;
auto forbidden_move(int index) -> MoveType&;
auto forbidden_move(int index) const -> const MoveType&;
auto clear_forbidden_moves() -> void;
auto nodes() -> int&;
auto nodes() const -> const int&;
auto trick_nodes() -> int&;
auto trick_nodes() const -> const int&;
auto ini_depth() -> int&;
auto ini_depth() const -> int;
public:
auto set_thread(const std::shared_ptr<ThreadData>& thr) -> void
{
thr_ = thr;
}
auto set_owner(SolverContext* owner) -> void
{
owner_ = owner;
}
private:
std::shared_ptr<ThreadData> thr_;
std::unique_ptr<TransTable> tt_;
SolverContext* owner_ = nullptr;
};
auto search() -> SearchContext&
{
return search_;
}
auto search() const -> const SearchContext&
{
return search_;
}
class MoveGenContext
{
public:
explicit MoveGenContext(std::shared_ptr<ThreadData> thr)
: thr_(std::move(thr))
{
}
auto move_gen_0(
const int tricks,
const Pos& tpos,
const MoveType& bestMove,
const MoveType& bestMoveTT,
const RelRanksType thrp_rel[]) -> int;
auto move_gen_123(
const int tricks,
const int relHand,
const Pos& tpos) -> int;
auto purge(
const int tricks,
const int relHand,
const MoveType forbiddenMoves[]) -> void;
auto make_next(
const int trick,
const int relHand,
const unsigned short win_ranks[]) -> const MoveType*;
auto make_next_simple(
const int trick,
const int relHand) -> const MoveType*;
auto get_length(
const int trick,
const int relHand) const -> int;
auto rewind(
const int tricks,
const int relHand) -> void;
auto register_hit(
const int tricks,
const int relHand) -> void;
auto reinit(
const int tricks,
const int leadHand) -> void;
auto init(
const int tricks,
const int relStartHand,
const int initialRanks[],
const int initialSuits[],
const unsigned short rank_in_suit[DDS_HANDS][DDS_SUITS],
const int trump,
const int leadHand) -> void;
auto print_trick_stats(std::ofstream& fout) const -> void;
auto print_trick_details(std::ofstream& fout) const -> void;
auto print_function_stats(std::ofstream& fout) const -> void;
auto get_trick_data(const int tricks) -> const TrickDataType&;
auto trick_to_text(const int trick) const -> std::string;
auto make_specific(
const MoveType& mply,
const int trick,
const int relHand) -> void;
private:
std::shared_ptr<ThreadData> thr_;
};
auto move_gen() const -> MoveGenContext
{
return MoveGenContext(thr_);
}
private:
std::shared_ptr<ThreadData> thr_;
SearchContext search_;
SolverConfig cfg_{};
mutable ::dds::Utilities utils_{};
};
auto ThreadMemoryUsed() -> double;