#pragma once

#include <cstdint>
#include <random>
#include <thread>
#include <unordered_map>

namespace overall_define{

    //全局变量
    inline std::mt19937 mt_rand;
    inline const int num_threads = std::thread::hardware_concurrency();
    // inline const int num_threads = 1;
    //常数
    // inline const int num_suits = 4;
    // inline const int num_ranks = 13;
    // inline const int total_cards = num_suits * num_ranks;
    inline const double epsilon = 1e-80;
    
    /* string constants */
    inline const char ROUND_SEPERATOR = '/';
}

//类型
namespace type{
using int_t = int32_t;
using uint_t = uint32_t;

using value_t = double;
using card_t = uint8_t;//  int;//
using chip_t = int; // uint16_t; // 40000 以内的数
using action_t = unsigned char;
using rank_t = int;

template<typename Key, typename T, typename Hash=std::hash<Key>, typename KeyEqual = std::equal_to<Key>>
using hash_table = std::unordered_map<Key, T, Hash, KeyEqual>;
}

//游戏模板
class PokerAssistBase{};
class PokerBase{};

//类模板
template<typename>
class Game;

template<typename>
class GameBase;

template<typename>
class Sequence;

template<typename>
class SequenceBase;

template<typename>
class Hand;

template<typename>
class HandBase;

template<typename>
class PlayerView;

template<typename>
class PlayerViewBase;

template<typename>
class Evaluator;

template<typename>
class EvaluatorBase;

template<typename>
class Abstraction;

template<typename>
class AbstractionBase;

template<typename, bool>
class RegretStrategy;

template<typename>
class Strategy;

namespace assist{

    template <auto Start, auto End, auto Inc, class F>
    inline constexpr void constexpr_for(F&& f)
    {
        if constexpr (Start < End)
        {
            f(std::integral_constant<decltype(Start), Start>());
            constexpr_for<Start + Inc, End, Inc>(f);
        }
    }
}