码迷,mamicode.com
首页 > 其他好文 > 详细

工作中标准库容器的运用(游戏编程需求)

时间:2018-03-06 17:07:29      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:queue   增加   lis   tab   序列   .com   png   ati   false   

C++标准库的容器分为序列容器和关联容器。

序列容器简单的有vectorlistdeque,复杂的还有配接器stackqueuepriority_queue

关联容器简单的有setmap,复杂的有multisetmultimap,这都是基于RB-tree的,基于hashtable的也有hash-sethash-maphash-multisethash-multimap。

工作中很多容器并不常用,常用的无非这几个vectorlistsetmapqueue。下面就简单总结一下这几个简单容器的适用需求(游戏功能逻辑方面的需求)。

 

1.vector

使用频率超高。通常我们使用数组是因为有明确的上限。而使用vector是因为有可能扩展。

有明确上限的,比如月签到系统。只需要一个31长度的数组,因为一个月最多31天。

没有明确上限的,比如成就系统。成就系统里的杀怪成就,一开始需求可能是10,100,1000,也就是杀怪10个,100个,1000个可以获得奖励。但是上线之后觉得数值不合适,需要多一个2000的条目。这种就非常适合用vector。

更多的情况其实是用数组和vector都行的。这种情况就需要编程者自己斟酌了。

看一个例子,等级礼包。如图:

 技术分享图片

我们先枚举出奖励的的各种状态。

enum RoleLevelRewardState
{
    RLR_INVALID = 0,            //不可领取
    RLR_CAN_GET,                //可领取
    RLR_HAS_GET,                //已领取
};

我们可以规定一个上限。这个上限是奖励的条目上限。如果策划需求改动了条目数量,比如加了一个100级的等级奖励,那我们就需要改动MAX_ROLE_REWARD这个值。

当然一般情况下,最好是扩展,而不改动已经存在的。因为要兼顾老玩家,比如老玩家已经100级了,前面领取过50,70,90级的奖励。但是这时策划需要增加一个60级的奖励…这就比较乱。最好和策划商量兼容老玩家。

如果是增加一个120级的奖励,这自然就比较简单。

static const int MAX_ROLE_REWARD = 3;

定义我们的数组:

int m_role_level_reward[MAX_ROLE_REWARD];

如果用vector,就是这样写:

std::vector<int> m_role_level_reward;

数组在构造函数里的初始化,或者重置清空通常是这样写:

memset(m_role_level_reward, 0, sizeof(m_role_level_reward));

vector初始化和清空就简单些:

m_role_level_reward.clear();

边界问题是我们需要重视的,在引用数组或vector元素时,都用首先判断边界。

bool UpdateRoleRewardState(int index)
{
    if (index < 0 || index >= MAX_ROLE_REWARD) return false;
        
    m_role_reward[index] = 1; //改变内容
    return true;     
}

更多的不同在于循环时:

for (int i = 0; i < MAX_ROLE_REWARD; ++i) // 数组
for (int i = 0; i < (int)m_role_level_reward.size() && i < MAX_ROLE_REWARD; ++i) // vector

(int)强转是因为.size()返回的是size_t类型,其实判断i < size已经足够,还要加上MAX_ROLE_REWARD是保证需求的数量限制和异常出现,较为稳妥。

 

2.list

有很多情况,需求可以使用list,也可以使用vector。其实只需要记得,如果需求需要随意在某个位置插入随意删除某个位置的记录,改变整体顺序的就用list,其他都可以用vector。

list是个循环的双向链表,vector是连续空间。所以list可以随意在任何位置插入,随意删除某个位置的记录,而vector不行。vector的insert和erase代价都很大。具体原理略过。

一个典型的例子,记录玩家杀死大boss的记录表。

首先它的数量肯定不确定的,所以数组不适合。而且要求只记录最近的50条。这就非常适合用list了。

因为我们肯定会有一个逻辑是记录数大于50的时候,删掉第1条记录。再把新的记录加到后面。

static const MAX_KILL_RECORD_NUM = 50;
if ((int)m_list.size() > MAX_KILL_RECORD_NUM)
{
    m_list.pop_front();
    //m_list.push_back();  //插入的数据结构略过
}

 

工作中标准库容器的运用(游戏编程需求)

标签:queue   增加   lis   tab   序列   .com   png   ati   false   

原文地址:https://www.cnblogs.com/yao2yaoblog/p/8514405.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!