从服务器排序并分发给客户端或发送未排序并让客户端排序更好吗?
Is it better to sort from server and distribute to clients or send unsorted and let clients sort it?
这是一个在线游戏,我得到报酬来实现一个游戏事件,这是一个玩家对玩家游戏系统。
在我的设计中,我有一个服务器端 class(名为 PvpEventManager
,它是事件管理器,当玩家杀死另一个玩家时,当玩家加入或离开事件时,它会处理,是它由决定、断开连接等决定,并具有许多其他功能。
现在,这个 class 还保存了一个容器,其中包含活动期间的玩家信息(名为 vPlayerInfo
),用于各种处理。当玩家杀死其他人时,他的 kill
必须增加,而受害者的 death
也必须增加,这很明显。但也有客户端有一个记分板的情况,因为服务器的工作是处理一个 kill 并告诉所有其他连接到该事件的客户端,容器将得到更新。
容器必须从 kill
结构成员从升序到降序排序,以便计分板可以正确呈现(在客户端)。
什么会更好?
- 在增加服务器工作量的服务器上对容器进行排序,并将已经排序的准备好在屏幕上呈现的容器发送给所有客户端。
- 发送未排序的容器,让每个连接的游戏客户端在接收容器时自行排序。
请注意,服务器每个滴答处理数以千计的传入和传出数据包,实际上处理了很多,很多 其他东西。
这在某种程度上描述了它的设计:
此代码描述了在部分实际代码上对容器进行排序时正在执行的操作。
#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <algorithm>
struct PlayerScoreBoardInfo
{
std::string name;
unsigned int kill, death, suicide;
unsigned int scorestreak;
PlayerScoreBoardInfo()
{
kill = death = suicide = scorestreak = 0;
name = "";
}
explicit PlayerScoreBoardInfo( std::string strname, unsigned int nkill, unsigned int ndeath, unsigned int nsuicide, unsigned int nscorestreak ) :
name(strname), kill(nkill), death(ndeath), suicide(nsuicide), scorestreak(nscorestreak)
{
}
};
class GameArenaManager
{
private:
GameArenaManager() {}
public:
std::map<u_long, PlayerScoreBoardInfo> m_Infos;
public:
static GameArenaManager& GetInstance()
{
static GameArenaManager InstanceObj;
return InstanceObj;
}
};
template <typename T1, typename T2> inline void SortVecFromMap( std::map<T1,T2>& maptodosort, std::vector<T2>& vectosort )
{
std::vector<T1> feedvector;
feedvector.reserve( maptodosort.size() );
for( const auto& it : maptodosort )
feedvector.push_back(it.second.kill);
std::sort(feedvector.begin(), feedvector.end(), std::greater<T1>());
for(const auto& itV : feedvector ) {
for( const auto& itM : maptodosort ) {
if( itM.second.kill == itV ) {
vectosort.push_back(itM.second );
}
}
}
}
int main()
{
GameArenaManager& Manager = GameArenaManager::GetInstance();
PlayerScoreBoardInfo info[5];
info[0] = PlayerScoreBoardInfo("ArchedukeShrimp", 5,4,0,0);
info[1] = PlayerScoreBoardInfo("EvilLactobacilus", 9,4,0,0);
info[2] = PlayerScoreBoardInfo("DolphinetelyOrcaward", 23,4,0,0);
info[3] = PlayerScoreBoardInfo("ChuckSkeet", 1,4,0,0);
info[4] = PlayerScoreBoardInfo("TrumpMcDuck", 87,4,0,0);
for( int i=0; i<5; i++)
Manager.m_Infos.insert( std::make_pair( i, info[i] ) );
std::vector<PlayerScoreBoardInfo> sortedvec;
SortVecFromMap( Manager.m_Infos, sortedvec );
for( std::vector<PlayerScoreBoardInfo>::iterator it = sortedvec.begin(); it != sortedvec.end(); it++ )
{
std::cout << "Name: " << (*it).name.c_str() << " ";
std::cout << "Kills: " << (*it).kill << std::endl;
}
return 0;
}
这里是ideone的link编译代码:http://ideone.com/B08y9l
还有一个 link 用于 Wandbox,以防您想实时编辑编译:http://melpon.org/wandbox/permlink/6OVLBGEXiux5Vn34
这个问题可能会因为 "off topic" 而被关闭。然而,
第一个问题:服务器是否需要排序记分板?
如果不是,为什么要做这份工作?
如果有的话,服务器将希望通过玩家 ID 为记分牌编制索引,这主张通过 ID 排序(以帮助二进制搜索)或使用散列容器(O1 搜索时间)。
此外,最终的瓶颈是网络带宽。您最终会希望能够发送记分板增量而不是 state-of-the-world 消息。
这进一步主张让客户完成求助的工作。
还有一个哲学论点:
按主键以外的任何方式排序是数据问题还是表现问题?这是一个演示问题。
演示文稿是什么?一个客户。
QED
这是一个在线游戏,我得到报酬来实现一个游戏事件,这是一个玩家对玩家游戏系统。
在我的设计中,我有一个服务器端 class(名为 PvpEventManager
,它是事件管理器,当玩家杀死另一个玩家时,当玩家加入或离开事件时,它会处理,是它由决定、断开连接等决定,并具有许多其他功能。
现在,这个 class 还保存了一个容器,其中包含活动期间的玩家信息(名为 vPlayerInfo
),用于各种处理。当玩家杀死其他人时,他的 kill
必须增加,而受害者的 death
也必须增加,这很明显。但也有客户端有一个记分板的情况,因为服务器的工作是处理一个 kill 并告诉所有其他连接到该事件的客户端,容器将得到更新。
容器必须从 kill
结构成员从升序到降序排序,以便计分板可以正确呈现(在客户端)。
什么会更好?
- 在增加服务器工作量的服务器上对容器进行排序,并将已经排序的准备好在屏幕上呈现的容器发送给所有客户端。
- 发送未排序的容器,让每个连接的游戏客户端在接收容器时自行排序。
请注意,服务器每个滴答处理数以千计的传入和传出数据包,实际上处理了很多,很多 其他东西。
这在某种程度上描述了它的设计:
此代码描述了在部分实际代码上对容器进行排序时正在执行的操作。
#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <algorithm>
struct PlayerScoreBoardInfo
{
std::string name;
unsigned int kill, death, suicide;
unsigned int scorestreak;
PlayerScoreBoardInfo()
{
kill = death = suicide = scorestreak = 0;
name = "";
}
explicit PlayerScoreBoardInfo( std::string strname, unsigned int nkill, unsigned int ndeath, unsigned int nsuicide, unsigned int nscorestreak ) :
name(strname), kill(nkill), death(ndeath), suicide(nsuicide), scorestreak(nscorestreak)
{
}
};
class GameArenaManager
{
private:
GameArenaManager() {}
public:
std::map<u_long, PlayerScoreBoardInfo> m_Infos;
public:
static GameArenaManager& GetInstance()
{
static GameArenaManager InstanceObj;
return InstanceObj;
}
};
template <typename T1, typename T2> inline void SortVecFromMap( std::map<T1,T2>& maptodosort, std::vector<T2>& vectosort )
{
std::vector<T1> feedvector;
feedvector.reserve( maptodosort.size() );
for( const auto& it : maptodosort )
feedvector.push_back(it.second.kill);
std::sort(feedvector.begin(), feedvector.end(), std::greater<T1>());
for(const auto& itV : feedvector ) {
for( const auto& itM : maptodosort ) {
if( itM.second.kill == itV ) {
vectosort.push_back(itM.second );
}
}
}
}
int main()
{
GameArenaManager& Manager = GameArenaManager::GetInstance();
PlayerScoreBoardInfo info[5];
info[0] = PlayerScoreBoardInfo("ArchedukeShrimp", 5,4,0,0);
info[1] = PlayerScoreBoardInfo("EvilLactobacilus", 9,4,0,0);
info[2] = PlayerScoreBoardInfo("DolphinetelyOrcaward", 23,4,0,0);
info[3] = PlayerScoreBoardInfo("ChuckSkeet", 1,4,0,0);
info[4] = PlayerScoreBoardInfo("TrumpMcDuck", 87,4,0,0);
for( int i=0; i<5; i++)
Manager.m_Infos.insert( std::make_pair( i, info[i] ) );
std::vector<PlayerScoreBoardInfo> sortedvec;
SortVecFromMap( Manager.m_Infos, sortedvec );
for( std::vector<PlayerScoreBoardInfo>::iterator it = sortedvec.begin(); it != sortedvec.end(); it++ )
{
std::cout << "Name: " << (*it).name.c_str() << " ";
std::cout << "Kills: " << (*it).kill << std::endl;
}
return 0;
}
这里是ideone的link编译代码:http://ideone.com/B08y9l
还有一个 link 用于 Wandbox,以防您想实时编辑编译:http://melpon.org/wandbox/permlink/6OVLBGEXiux5Vn34
这个问题可能会因为 "off topic" 而被关闭。然而,
第一个问题:服务器是否需要排序记分板?
如果不是,为什么要做这份工作?
如果有的话,服务器将希望通过玩家 ID 为记分牌编制索引,这主张通过 ID 排序(以帮助二进制搜索)或使用散列容器(O1 搜索时间)。
此外,最终的瓶颈是网络带宽。您最终会希望能够发送记分板增量而不是 state-of-the-world 消息。
这进一步主张让客户完成求助的工作。
还有一个哲学论点:
按主键以外的任何方式排序是数据问题还是表现问题?这是一个演示问题。
演示文稿是什么?一个客户。
QED