1. #1
    Banned cqwrteur's Avatar
    7+ Year Old Account
    Join Date
    Sep 2014
    Location
    Shanghai, China
    Posts
    1,932

    C++ code to mimic GotS

    Code:
    #include <iostream>
    #include<fstream>
    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/segment.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include<chrono>
    #include<random>
    #include<iomanip>
    #include<exception>
    #define _VCP_BEGIN namespace vcp{ namespace{
    #define _VCP_END }}
    _VCP_BEGIN
    
    using namespace std::chrono_literals;
    //WOW system constants:
    constexpr auto movement_speed(7.05);		//players max movement speed : Unit(yards/sec)
    constexpr auto life_time(30s);				//spheres existed duration : Unit(sec)
    constexpr double expired_radius(12);
    constexpr double sphere_radius(8);
    constexpr double touch_radius(3);			//I find this radius affects GotS effective greatly.
    
    
    //Here are tested constants:
    constexpr std::size_t test_times(200);		//tested for 200 times
    constexpr std::size_t mans(20);			//suppose a 20-man raid
    constexpr double player_range_x(30),player_range_y(30);		//Suppose player init positions ranges
    constexpr double range_x(100),range_y(100);		//Suppose map ranges
    constexpr auto combat_duration(400s);		//Suppose combat duration is 400 sec
    constexpr std::size_t sphere_proc_rate(4);		//max spheres proc per second
    
    static_assert(combat_duration!=0s,"combat_duration should not be 0s.");
    static_assert(mans,"mans should not be 0.");
    static_assert(player_range_x<=range_x,"player_range_x should <= range_x");
    static_assert(player_range_y<=range_y,"player_range_y should <= range_y");
    
    std::random_device rd;
    std::mt19937_64 eng(rd());
    using point = boost::geometry::model::d2::point_xy<double>;
    using segment = boost::geometry::model::segment<point>;
    using boost::geometry::distance;
    std::uniform_int_distribution<std::size_t> ds_sp_pr(0,sphere_proc_rate);
    std::uniform_real_distribution<double> ds_sp(-sphere_radius,sphere_radius),
    						ds_range_x(-player_range_x,player_range_x),
    						ds_range_y(-player_range_y,player_range_y),
    						ds_mv(-movement_speed,movement_speed);
    
    class healing_sphere
    {
    	point sphere_location;
    	std::chrono::seconds lftm = 0s;
    public:
    	healing_sphere(const point &p=point()) : sphere_location(p){}
    	const point & location() const
    	{
    		return sphere_location;
    	}
    	point& location()
    	{
    		return sphere_location;
    	}
    	bool expired()
    	{
    		return life_time<=++lftm;
    	}
    	template<typename Iter>
    	bool expired_ef(Iter beg,Iter end)
    	{
    		for(;beg!=end;++beg)
    			if(distance(beg->location(),sphere_location)<=expired_radius)
    				return true;
    		return false;
    	}
    };
    class player
    {
    	point player_location;
    public:
    	const point & location() const
    	{
    		return player_location;
    	}
    	point& location()
    	{
    		return player_location;
    	}
    	player():player_location(ds_range_x(eng),ds_range_y(eng)){}
    	std::size_t wander(std::vector<healing_sphere> &healing_sphere_vec)
    	{
    		auto dx(ds_mv(eng)),dy(sqrt(movement_speed*movement_speed-dx * dx));
    		std::uniform_real_distribution<double> ud(-dy,dy);
    		point wandered_position(player_location.x()+ dx,player_location.y() + ud(eng));
    		if(range_x<wandered_position.x())
    			wandered_position.x(range_x);
    		if(range_y<wandered_position.y())
    			wandered_position.y(range_y);
    		segment seg(player_location,wandered_position);
    		player_location = wandered_position;
    		std::vector<healing_sphere> nv;
    		nv.reserve(healing_sphere_vec.size());
    		std::size_t pick(0);
    		for(const auto &ele : healing_sphere_vec)
    			if(distance(seg,ele.location())<=touch_radius)
    				++pick;
    			else
    				nv.push_back(ele);
    		healing_sphere_vec = std::move(nv);
    		return pick;
    	}
    	healing_sphere summon_sphere()
    	{
    		auto dx(ds_sp(eng)),dy(sqrt(sphere_radius*sphere_radius-dx * dx));
    		std::uniform_real_distribution<double> ud(-dy,dy);
    		point p(player_location.x() + dx,player_location.y() + ud(eng));
    		if(range_x<fabs(p.x()))
    			p.x(range_x);
    		if(range_y<fabs(p.y()))
    			p.y(range_y);
    		return p;
    	}
    };
    
    void process()
    {
    	std::uniform_int_distribution<std::size_t> ud(0,mans-1);
    
    	std::size_t expired_orb(0),pickup(0),wasted(0),total(0);
    	for (std::size_t t(0);t!=test_times;++t)
    	{
    		std::vector<player> vplayers(mans);
    		std::vector<healing_sphere> vhsp;
    		for(std::chrono::seconds i(0);i!=combat_duration;++i)
    		{
    			for(auto &ele : vplayers)
    				pickup+=ele.wander(vhsp);
    			std::size_t tt(ds_sp_pr(eng));
    			total += tt;
    			for(std::size_t i(0);i!=tt;++i)
    				vhsp.push_back(vplayers[ud(eng)].summon_sphere());
    			std::vector<healing_sphere> v;
    			v.reserve(vhsp.size());
    			for(auto &ele : vhsp)
    				if(ele.expired())
    				{
    					if(ele.expired_ef(vplayers.cbegin(),vplayers.cend()))
    						++expired_orb;
    					else
    						++wasted;
    				}
    				else
    					v.push_back(ele);
    			vhsp = std::move(v);
    		}
    	}
    	auto effective(pickup+expired_orb);
    	std::ofstream fout("result.txt");
    	auto &rdbuf(*fout.rdbuf());
    	fout<<mans;
    	rdbuf.sputn("-man Raid\nPick Up: ",19);
    	fout<<pickup;
    	rdbuf.sputn("\nExpired: ",10);
    	fout<<expired_orb;
    	rdbuf.sputn("\nWasted: ",9);
    	fout<<wasted;
    	rdbuf.sputn("\nEffective: ",12);
    	fout<<effective;
    	rdbuf.sputn("\nExisted: ",10);
    	fout<<total-effective-wasted;
    	rdbuf.sputn("\nTotal: ",8);
    	fout<<total;
    	rdbuf.sputn("\nEffective Rate: ",17);
    	fout<<std::fixed<<std::setprecision(2);
    	fout<<static_cast<double>(expired_orb+pickup)/total * 100;
    	rdbuf.sputn("%\n",2);
    }
    
    _VCP_END
    
    int main()
    {
    	try
    	{
    		vcp::process();
    	}
    	catch(std::exception &ex)
    	{
    		std::cerr<<ex.what()<<std::endl;
    	}
    	catch(...)
    	{
    		std::cerr<<"Unknown Error"<<std::endl;
    	}
    	return 0;
    }
    - - - Updated - - -

    These following testcases(1-4) suppose everyone moves at every second.


    Testcase 1 (for 2v2 Arena):
    2-man Raid
    Pick Up: 89659
    Expired: 6419
    Wasted: 57371
    Effective: 96078
    Existed: 6151
    Total: 159600
    Effective Rate: 60.20%

    Testcase 2 (for mythic raid):
    20-man Raid
    Pick Up: 112708
    Expired: 9799
    Wasted: 32570
    Effective: 122507
    Existed: 5331
    Total: 160408
    Effective Rate: 76.37%

    Testcase 3 (for 30-man heroic Raid):
    30-man Raid
    Pick Up: 120314
    Expired: 9975
    Wasted: 24409
    Effective: 130289
    Existed: 4701
    Total: 159399
    Effective Rate: 81.74%



    Testcase 4 (for World PVP):
    40-man Raid
    Pick Up: 126353
    Expired: 9366
    Wasted: 19159
    Effective: 135719
    Existed: 4347
    Total: 159225
    Effective Rate: 85.24%

    In most cases, we won't move at every second. Our "Real" movement speed might be only 1/3 of the movement speed.
    We change line 16:
    Code:
    constexpr auto movement_speed(7.05);		//players max movement speed : Unit(yards/sec)
    To
    Code:
    constexpr auto movement_speed(7.05/3);		//players max movement speed : Unit(yards/sec)
    Then test again. Now we get Testcase 5-8:
    Testcase 5 (for 2v2 Arena):
    2-man Raid
    Pick Up: 77028
    Expired: 41052
    Wasted: 34690
    Effective: 118080
    Existed: 7246
    Total: 160016
    Effective Rate: 73.79%

    Testcase 6 (for mythic raid):
    20-man Raid
    Pick Up: 99629
    Expired: 39626
    Wasted: 13442
    Effective: 139255
    Existed: 6413
    Total: 159110
    Effective Rate: 87.52%

    Testcase 7 (for 30-man heroic Raid):
    30-man Raid
    Pick Up: 108900
    Expired: 35221
    Wasted: 9394
    Effective: 144121
    Existed: 6129
    Total: 159644
    Effective Rate: 90.28%


    Testcase 8 (for World PVP):
    40-man Raid
    Pick Up: 116038
    Expired: 31252
    Wasted: 6793
    Effective: 147290
    Existed: 5696
    Total: 159779
    Effective Rate: 92.18%

    - - - Updated - - -

    What if no expired healing spheres?
    Code:
    #include <iostream>
    #include<fstream>
    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/segment.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include<chrono>
    #include<random>
    #include<iomanip>
    #include<exception>
    #define _VCP_BEGIN namespace vcp{ namespace{
    #define _VCP_END }}
    _VCP_BEGIN
    
    using namespace std::chrono_literals;
    //WOW system constants:
    constexpr auto movement_speed(7.05);		//players max movement speed : Unit(yards/sec)
    constexpr auto life_time(30s);				//spheres existed duration : Unit(sec)
    constexpr double expired_radius(12);
    constexpr double sphere_radius(8);
    constexpr double touch_radius(3);			//I find this radius affects GotS effective greatly.
    
    
    //Here are tested constants:
    constexpr std::size_t test_times(200);		//tested for 200 times
    constexpr std::size_t mans(20);			//suppose a 20-man raid
    constexpr double player_range_x(30),player_range_y(30);		//Suppose player init positions ranges
    constexpr double range_x(100),range_y(100);		//Suppose map ranges
    constexpr auto combat_duration(400s);		//Suppose combat duration is 400 sec
    constexpr std::size_t sphere_proc_rate(4);		//max spheres proc per second
    
    static_assert(combat_duration!=0s,"combat_duration should not be 0s.");
    static_assert(mans,"mans should not be 0.");
    static_assert(player_range_x<=range_x,"player_range_x should <= range_x");
    static_assert(player_range_y<=range_y,"player_range_y should <= range_y");
    
    std::random_device rd;
    std::mt19937_64 eng(rd());
    using point = boost::geometry::model::d2::point_xy<double>;
    using segment = boost::geometry::model::segment<point>;
    using boost::geometry::distance;
    std::uniform_int_distribution<std::size_t> ds_sp_pr(0,sphere_proc_rate);
    std::uniform_real_distribution<double> ds_sp(-sphere_radius,sphere_radius),
    						ds_range_x(-player_range_x,player_range_x),
    						ds_range_y(-player_range_y,player_range_y),
    						ds_mv(-movement_speed,movement_speed);
    
    class healing_sphere
    {
    	point sphere_location;
    	std::chrono::seconds lftm = 0s;
    public:
    	healing_sphere(const point &p=point()) : sphere_location(p){}
    	const point & location() const
    	{
    		return sphere_location;
    	}
    	point& location()
    	{
    		return sphere_location;
    	}
    	bool expired()
    	{
    		return life_time<=++lftm;
    	}
    	template<typename Iter>
    	bool expired_ef(Iter beg,Iter end)
    	{
    /*		for(;beg!=end;++beg)
    			if(distance(beg->location(),sphere_location)<=expired_radius)
    				return true;*/
    		return false;
    	}
    };
    class player
    {
    	point player_location;
    public:
    	const point & location() const
    	{
    		return player_location;
    	}
    	point& location()
    	{
    		return player_location;
    	}
    	player():player_location(ds_range_x(eng),ds_range_y(eng)){}
    	std::size_t wander(std::vector<healing_sphere> &healing_sphere_vec)
    	{
    		auto dx(ds_mv(eng)),dy(sqrt(movement_speed*movement_speed-dx * dx));
    		std::uniform_real_distribution<double> ud(-dy,dy);
    		point wandered_position(player_location.x()+ dx,player_location.y() + ud(eng));
    		if(range_x<fabs(wandered_position.x()))
    			wandered_position.x(range_x);
    		if(range_y<fabs(wandered_position.y()))
    			wandered_position.y(range_y);
    		segment seg(player_location,wandered_position);
    		player_location = wandered_position;
    		std::vector<healing_sphere> nv;
    		nv.reserve(healing_sphere_vec.size());
    		std::size_t pick(0);
    		for(const auto &ele : healing_sphere_vec)
    			if(distance(seg,ele.location())<=touch_radius)
    				++pick;
    			else
    				nv.push_back(ele);
    		healing_sphere_vec = std::move(nv);
    		return pick;
    	}
    	healing_sphere summon_sphere()
    	{
    		auto dx(ds_sp(eng)),dy(sqrt(sphere_radius*sphere_radius-dx * dx));
    		std::uniform_real_distribution<double> ud(-dy,dy);
    		point p(player_location.x() + dx,player_location.y() + ud(eng));
    		if(range_x<fabs(p.x()))
    			p.x(range_x);
    		if(range_y<fabs(p.y()))
    			p.y(range_y);
    		return p;
    	}
    };
    
    void process()
    {
    	std::uniform_int_distribution<std::size_t> ud(0,mans-1);
    
    	std::size_t expired_orb(0),pickup(0),wasted(0),total(0);
    	for (std::size_t t(0);t!=test_times;++t)
    	{
    		std::vector<player> vplayers(mans);
    		std::vector<healing_sphere> vhsp;
    		for(std::chrono::seconds i(0);i!=combat_duration;++i)
    		{
    			for(auto &ele : vplayers)
    				pickup+=ele.wander(vhsp);
    			std::size_t tt(ds_sp_pr(eng));
    			total += tt;
    			for(std::size_t i(0);i!=tt;++i)
    				vhsp.push_back(vplayers[ud(eng)].summon_sphere());
    			std::vector<healing_sphere> v;
    			v.reserve(vhsp.size());
    			for(auto &ele : vhsp)
    				if(ele.expired())
    				{
    					if(ele.expired_ef(vplayers.cbegin(),vplayers.cend()))
    						++expired_orb;
    					else
    						++wasted;
    				}
    				else
    					v.push_back(ele);
    			vhsp = std::move(v);
    		}
    	}
    	auto effective(pickup+expired_orb);
    	std::ofstream fout("result.txt");
    	auto &rdbuf(*fout.rdbuf());
    	fout<<mans;
    	rdbuf.sputn("-man Raid\nPick Up: ",19);
    	fout<<pickup;
    	rdbuf.sputn("\nExpired: ",10);
    	fout<<expired_orb;
    	rdbuf.sputn("\nWasted: ",9);
    	fout<<wasted;
    	rdbuf.sputn("\nEffective: ",12);
    	fout<<effective;
    	rdbuf.sputn("\nExisted: ",10);
    	fout<<total-effective-wasted;
    	rdbuf.sputn("\nTotal: ",8);
    	fout<<total;
    	rdbuf.sputn("\nEffective Rate: ",17);
    	fout<<std::fixed<<std::setprecision(2);
    	fout<<static_cast<double>(expired_orb+pickup)/total * 100;
    	rdbuf.sputn("%\n",2);
    }
    
    _VCP_END
    
    int main()
    {
    	try
    	{
    		vcp::process();
    	}
    	catch(std::exception &ex)
    	{
    		std::cerr<<ex.what()<<std::endl;
    	}
    	catch(...)
    	{
    		std::cerr<<"Unknown Error"<<std::endl;
    	}
    	return 0;
    }
    20-man Raid
    Pick Up: 112403
    Expired: 0
    Wasted: 41995
    Effective: 112403
    Existed: 5211
    Total: 159609
    Effective Rate: 70.42%

    Code:
    #include <iostream>
    #include<fstream>
    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/segment.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include<chrono>
    #include<random>
    #include<iomanip>
    #include<exception>
    #define _VCP_BEGIN namespace vcp{ namespace{
    #define _VCP_END }}
    _VCP_BEGIN
    
    using namespace std::chrono_literals;
    //WOW system constants:
    constexpr auto movement_speed(7.05/3);		//players max movement speed : Unit(yards/sec)
    constexpr auto life_time(30s);				//spheres existed duration : Unit(sec)
    constexpr double expired_radius(12);
    constexpr double sphere_radius(8);
    constexpr double touch_radius(3);			//I find this radius affects GotS effective greatly.
    
    
    //Here are tested constants:
    constexpr std::size_t test_times(200);		//tested for 200 times
    constexpr std::size_t mans(20);			//suppose a 20-man raid
    constexpr double player_range_x(30),player_range_y(30);		//Suppose player init positions ranges
    constexpr double range_x(100),range_y(100);		//Suppose map ranges
    constexpr auto combat_duration(400s);		//Suppose combat duration is 400 sec
    constexpr std::size_t sphere_proc_rate(4);		//max spheres proc per second
    
    static_assert(combat_duration!=0s,"combat_duration should not be 0s.");
    static_assert(mans,"mans should not be 0.");
    static_assert(player_range_x<=range_x,"player_range_x should <= range_x");
    static_assert(player_range_y<=range_y,"player_range_y should <= range_y");
    
    std::random_device rd;
    std::mt19937_64 eng(rd());
    using point = boost::geometry::model::d2::point_xy<double>;
    using segment = boost::geometry::model::segment<point>;
    using boost::geometry::distance;
    std::uniform_int_distribution<std::size_t> ds_sp_pr(0,sphere_proc_rate);
    std::uniform_real_distribution<double> ds_sp(-sphere_radius,sphere_radius),
    						ds_range_x(-player_range_x,player_range_x),
    						ds_range_y(-player_range_y,player_range_y),
    						ds_mv(-movement_speed,movement_speed);
    
    class healing_sphere
    {
    	point sphere_location;
    	std::chrono::seconds lftm = 0s;
    public:
    	healing_sphere(const point &p=point()) : sphere_location(p){}
    	const point & location() const
    	{
    		return sphere_location;
    	}
    	point& location()
    	{
    		return sphere_location;
    	}
    	bool expired()
    	{
    		return life_time<=++lftm;
    	}
    	template<typename Iter>
    	bool expired_ef(Iter beg,Iter end)
    	{
    /*		for(;beg!=end;++beg)
    			if(distance(beg->location(),sphere_location)<=expired_radius)
    				return true;*/
    		return false;
    	}
    };
    class player
    {
    	point player_location;
    public:
    	const point & location() const
    	{
    		return player_location;
    	}
    	point& location()
    	{
    		return player_location;
    	}
    	player():player_location(ds_range_x(eng),ds_range_y(eng)){}
    	std::size_t wander(std::vector<healing_sphere> &healing_sphere_vec)
    	{
    		auto dx(ds_mv(eng)),dy(sqrt(movement_speed*movement_speed-dx * dx));
    		std::uniform_real_distribution<double> ud(-dy,dy);
    		point wandered_position(player_location.x()+ dx,player_location.y() + ud(eng));
    		if(range_x<fabs(wandered_position.x()))
    			wandered_position.x(range_x);
    		if(range_y<fabs(wandered_position.y()))
    			wandered_position.y(range_y);
    		segment seg(player_location,wandered_position);
    		player_location = wandered_position;
    		std::vector<healing_sphere> nv;
    		nv.reserve(healing_sphere_vec.size());
    		std::size_t pick(0);
    		for(const auto &ele : healing_sphere_vec)
    			if(distance(seg,ele.location())<=touch_radius)
    				++pick;
    			else
    				nv.push_back(ele);
    		healing_sphere_vec = std::move(nv);
    		return pick;
    	}
    	healing_sphere summon_sphere()
    	{
    		auto dx(ds_sp(eng)),dy(sqrt(sphere_radius*sphere_radius-dx * dx));
    		std::uniform_real_distribution<double> ud(-dy,dy);
    		point p(player_location.x() + dx,player_location.y() + ud(eng));
    		if(range_x<fabs(p.x()))
    			p.x(range_x);
    		if(range_y<fabs(p.y()))
    			p.y(range_y);
    		return p;
    	}
    };
    
    void process()
    {
    	std::uniform_int_distribution<std::size_t> ud(0,mans-1);
    
    	std::size_t expired_orb(0),pickup(0),wasted(0),total(0);
    	for (std::size_t t(0);t!=test_times;++t)
    	{
    		std::vector<player> vplayers(mans);
    		std::vector<healing_sphere> vhsp;
    		for(std::chrono::seconds i(0);i!=combat_duration;++i)
    		{
    			for(auto &ele : vplayers)
    				pickup+=ele.wander(vhsp);
    			std::size_t tt(ds_sp_pr(eng));
    			total += tt;
    			for(std::size_t i(0);i!=tt;++i)
    				vhsp.push_back(vplayers[ud(eng)].summon_sphere());
    			std::vector<healing_sphere> v;
    			v.reserve(vhsp.size());
    			for(auto &ele : vhsp)
    				if(ele.expired())
    				{
    					if(ele.expired_ef(vplayers.cbegin(),vplayers.cend()))
    						++expired_orb;
    					else
    						++wasted;
    				}
    				else
    					v.push_back(ele);
    			vhsp = std::move(v);
    		}
    	}
    	auto effective(pickup+expired_orb);
    	std::ofstream fout("result.txt");
    	auto &rdbuf(*fout.rdbuf());
    	fout<<mans;
    	rdbuf.sputn("-man Raid\nPick Up: ",19);
    	fout<<pickup;
    	rdbuf.sputn("\nExpired: ",10);
    	fout<<expired_orb;
    	rdbuf.sputn("\nWasted: ",9);
    	fout<<wasted;
    	rdbuf.sputn("\nEffective: ",12);
    	fout<<effective;
    	rdbuf.sputn("\nExisted: ",10);
    	fout<<total-effective-wasted;
    	rdbuf.sputn("\nTotal: ",8);
    	fout<<total;
    	rdbuf.sputn("\nEffective Rate: ",17);
    	fout<<std::fixed<<std::setprecision(2);
    	fout<<static_cast<double>(expired_orb+pickup)/total * 100;
    	rdbuf.sputn("%\n",2);
    }
    
    _VCP_END
    
    int main()
    {
    	try
    	{
    		vcp::process();
    	}
    	catch(std::exception &ex)
    	{
    		std::cerr<<ex.what()<<std::endl;
    	}
    	catch(...)
    	{
    		std::cerr<<"Unknown Error"<<std::endl;
    	}
    	return 0;
    }
    20-man Raid
    Pick Up: 100468
    Expired: 0
    Wasted: 53837
    Effective: 100468
    Existed: 6566
    Total: 160871
    Effective Rate: 62.45%
    Last edited by cqwrteur; 2015-08-06 at 02:36 PM. Reason: Code Error

  2. #2
    Herald of the Titans Babylonius's Avatar
    10+ Year Old Account
    Join Date
    May 2009
    Location
    Behind you
    Posts
    2,871
    You may want to explain exactly what we're looking at here as I feel like I'm seeing the end of a very long and detailed conversation that doesn't exist anywhere.
    Creator of WalkingTheWind.com and PeakOfSerenity.com
    Former Monk Mod of MMOChampion | Admin/Moderator of Monk Discord
    Armory | Logs | Guild | Twitch

  3. #3
    Bloodsail Admiral Moxal's Avatar
    15+ Year Old Account
    Join Date
    Oct 2008
    Location
    Space Coast, US
    Posts
    1,067
    Maybe link to a github repository or perhaps several gists instead?

    Also, moar comments in your logic would be helpful.

    And I would have personally used a scripting language for this. Less barrier for others to test it out than having either a Linux box, Visual Studio or some sort of Cygwin/mingw setup going.

  4. #4
    Banned cqwrteur's Avatar
    7+ Year Old Account
    Join Date
    Sep 2014
    Location
    Shanghai, China
    Posts
    1,932
    Quote Originally Posted by Babylonius View Post
    You may want to explain exactly what we're looking at here as I feel like I'm seeing the end of a very long and detailed conversation that doesn't exist anywhere.
    Mythic Raid(20-man Raid):
    Effective Rate: 87.52%

    - - - Updated - - -

    Quote Originally Posted by Moxal View Post
    Maybe link to a github repository or perhaps several gists instead?

    Also, moar comments in your logic would be helpful.

    And I would have personally used a scripting language for this. Less barrier for others to test it out than having either a Linux box, Visual Studio or some sort of Cygwin/mingw setup going.
    Script language is not that helpful I think. I use boost.geometry library to avoid the math details. The math is too complex to understand.
    Boost Library is the well-known pre-std C++ library.
    boost:
    http://www.boost.org/

    visual studio 2015 community (free):
    https://www.visualstudio.com/downloa...sual-studio-vs
    nuwen mingw:
    http://nuwen.net/mingw.html

    I think Linux-gcc will be better than a mingw. There is no REAL random engine in mingw. "std::random_device" will be useless.

    C++ standard random library is also a famous high-quality library.
    Last edited by cqwrteur; 2015-08-06 at 03:56 PM.

  5. #5
    Bloodsail Admiral Moxal's Avatar
    15+ Year Old Account
    Join Date
    Oct 2008
    Location
    Space Coast, US
    Posts
    1,067
    Quote Originally Posted by cqwrteur View Post
    Script language is not that helpful I think. I use boost.geometry library to avoid the math details. The math is too complex to understand.
    Boost Library is the well-known pre-std C++ library.
    boost:
    http://www.boost.org/

    visual studio 2015 community (free):
    https://www.visualstudio.com/downloa...sual-studio-vs
    nuwen mingw:
    http://nuwen.net/mingw.html

    I think Linux-gcc will be better than a mingw. There is no REAL random engine in mingw. "std::random_device" will be useless.

    C++ standard random library is also a famous high-quality library.
    While all true, it will still be considerably more readable if you post it to github or similar. Syntax highlighting, etc.
    Mistweaver Monk | Holy Priest

  6. #6
    Banned cqwrteur's Avatar
    7+ Year Old Account
    Join Date
    Sep 2014
    Location
    Shanghai, China
    Posts
    1,932
    Quote Originally Posted by Moxal View Post
    While all true, it will still be considerably more readable if you post it to github or similar. Syntax highlighting, etc.
    https://github.com/euloanty/GotS/tre...f19c32d6bb76ae

    a.cc
    Last edited by cqwrteur; 2015-08-07 at 03:05 AM.

  7. #7
    Ok but that doesn't match logs, so you got something wrong?
    Legion Mistweaver Stat Weights SPREADSHEET --- Stat weights DISCUSSION THREAD
    Follow @GeodewMW for off-topic funsies and notifications for important MW theorycrafting posts!
    IF WE MISS YOUR QUESTION, please ask again! You're not being annoying, I promise

  8. #8
    Banned cqwrteur's Avatar
    7+ Year Old Account
    Join Date
    Sep 2014
    Location
    Shanghai, China
    Posts
    1,932
    Quote Originally Posted by Geodew View Post
    Ok but that doesn't match logs, so you got something wrong?
    If Expired == 0:

    20-man Raid
    Pick Up: 100468
    Expired: 0
    Wasted: 53837
    Effective: 100468
    Existed: 6566
    Total: 160871
    Effective Rate: 62.45%

  9. #9
    Quote Originally Posted by cqwrteur View Post
    If Expired == 0:

    20-man Raid
    Pick Up: 100468
    Expired: 0
    Wasted: 53837
    Effective: 100468
    Existed: 6566
    Total: 160871
    Effective Rate: 62.45%
    Yeah, but we're seeing ~70% for a typical fight including expirations. 87% is both far off from that and too different from 62%, so some of your assumptions/estimations need adjustment.

    Even then, if you tweak until you match logs, you're essentially using a sort of confirmation bias, so all that really means is that you can estimate pickup rates for other raid sizes or arena based on mythic logs.
    Legion Mistweaver Stat Weights SPREADSHEET --- Stat weights DISCUSSION THREAD
    Follow @GeodewMW for off-topic funsies and notifications for important MW theorycrafting posts!
    IF WE MISS YOUR QUESTION, please ask again! You're not being annoying, I promise

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •