#pragma once #include #include #include #include /* // È®·ü(DWORD)¿¡ µû¶ó¼­ ActionÀ» Çϳª ¼±ÅÃÇÑ´Ù. RatioSelector rs(); rs.Add( 1, 20 ); rs.Add( 2, 10 ); rs.Add( 3, 50 ); rs.Add( 4, 30 ); //rs.GenerateRatios(); // ¾ÈÇØµµ Select()³ª GetTotalRatio()¿¡¼­ ÀÚµ¿À¸·Î µÊ. // m_RatiosÀÇ °ªµé // Action Ratio ÁöÁ¤µÈ ¹üÀ§ // [19] = 1 // 1 20 0~19 // [29] = 2 // 2 10 20~29 // [79] = 3 // 3 50 30~79 // [109] = 4 // 4 30 80~109 int a; assert( rs.Select( 0, a ) ); assert( a == 1 ); assert( rs.Select( 19, a ) ); assert( a == 1 ); assert( rs.Select( 20, a ) ); assert( a == 2 ); assert( rs.Select( 21, a ) ); assert( a == 2 ); assert( rs.Select( 81, a ) ); assert( a == 4 ); assert( rs.Select( 109, a ) ); assert( a == 4 ); assert( !rs.Select( 110, a ) ); // 110Àº ¹üÀ§¸¦ ¹þ¾î³ª¹Ç·Î ½ÇÆÐ. a°ªÀº Àǹ̾ø´Ù. */ // È®·ü ¼±Åñâ Á¢±Ù ¹æ½Ä struct RatioAccessMode { enum Value { kMutable = 0, // kConst = 1 // »ó¼ö·Î¸¸ Á¢±Ù }; }; // GenerateRatios()°¡ ÀÚµ¿À¸·Î È£ÃâµÇ´Â ³»ºÎ ¸â¹ö º¯°æÀÌ ÀϾ´Â ¹öÀü template < typename ActionT, typename RatioT = DWORD, RatioT kMaxTotalRatio = 0, RatioAccessMode::Value kRatioAccessMode = RatioAccessMode::kMutable > class RatioSelector { public: typedef stdext::hash_map ACTIONS; RatioSelector() : is_generate_(true), total_ratio_(0) { } ~RatioSelector() {} void Release() { is_generate_ = true; total_ratio_ = 0; actions_.clear(); ratios_.clear(); } BOOL Add(const ActionT action, const RatioT ratio) { ACTIONS::const_iterator it = actions_.find(action); if (it != actions_.end()) { return FALSE; } actions_[action] = ratio; is_generate_ = false; return TRUE; } BOOL Remove(const ActionT action) { ACTIONS::iterator it = actions_.find(action); if (it != actions_.end()) { actions_.erase(it); is_generate_ = false; return TRUE; } return FALSE; } void GenerateRatios() { ratios_.clear(); total_ratio_ = 0; ACTIONS::const_iterator it = actions_.begin(); for (; it != actions_.end(); it++) { const ActionT& action = it->first; const RatioT ratio = it->second; total_ratio_ += ratio; #ifdef _NA_007667_20141001_WITCHBLADE_SKILL ratios_[total_ratio_] = action; #else // ½ÇÁ¦·Î´Â -1±îÁö°¡ actionÀÌ ¼±ÅõǴ ¿µ¿ªÀÌ´Ù. // ex) ratio=20À̸é, 0~19±îÁö. ratios_[total_ratio_-1] = action; #endif //_NA_007667_20141001_WITCHBLADE_SKILL } is_generate_ = true; } BOOL Select(const RatioT ratio, ActionT& selectedAction) { if (is_generate_ == false) { GenerateRatios(); } Ratios::const_iterator it = ratios_.lower_bound(ratio); if (it == ratios_.end()) { return FALSE; } selectedAction = it->second; return TRUE; } RatioT GetTotalRatio() { if (is_generate_ == false) { GenerateRatios(); } return total_ratio_; } std::size_t GetCount() const { return actions_.size(); } ACTIONS& GetActionData() { return actions_; } private: typedef std::map Ratios; bool is_generate_; RatioT total_ratio_; ACTIONS actions_; Ratios ratios_; }; // ÃʱâÈ­ ½ÃÁ¡¿¡ È®·ü Á¤º¸¸¦ Ãß°¡Çϰí ÀÌÈÄ »ó¼ö Á¢±ÙÀ¸·Î¸¸ »ç¿ëÇÏ´Â ¹öÀü template class RatioSelector { public: RatioSelector() : total_ratio_(0), distribution_(1, kMaxTotalRatio), generator_(RandomEngine(std::time(NULL)), distribution_) { } ~RatioSelector() {} bool Add(const ActionT action, const RatioT ratio) { if (ratio <= 0) { return false; } if (total_ratio_ >= kMaxTotalRatio) { return false; } Actions::const_iterator it = actions_.find(action); if (it != actions_.end()) { return false; } actions_[action] = ratio; total_ratio_ += ratio; #ifdef _NA_007667_20141001_WITCHBLADE_SKILL const RatioT ratio_key = total_ratio_; #else const RatioT ratio_key = total_ratio_-1; #endif //_NA_007667_20141001_WITCHBLADE_SKILL ratios_[ratio_key] = action; return true; } bool Select(const RatioT ratio, ActionT& OUT selected_action) const { Ratios::const_iterator it = ratios_.lower_bound(ratio); if (it == ratios_.end()) { return false; } selected_action = it->second; return true; } bool RandomSelect(ActionT& OUT selected_action) const { RandomGenerator& generate = const_cast(generator_); const RatioT ratio = generate(); Ratios::const_iterator it = ratios_.lower_bound(ratio); if (it == ratios_.end()) { return false; } selected_action = it->second; return true; } RatioT GetTotalRatio() const { return total_ratio_; } std::size_t GetCount() const { return actions_.size(); } private: typedef stdext::hash_map Actions; typedef std::map Ratios; typedef boost::lagged_fibonacci607 RandomEngine; typedef boost::uniform_int RandomDistribution; typedef boost::variate_generator RandomGenerator; RatioT total_ratio_; Actions actions_; Ratios ratios_; RandomDistribution distribution_; RandomGenerator generator_; };