竞技场往往是游戏中不可缺少的系统,根据不同的需求类型,竞技场排行榜的类型可以有如下划分:

1.按照排名更新的方式划分:依靠积分进行排行的竞技场,当玩家完成挑战后根据一定的规则进行双方积分的增减,依据新的积分进行重新排名;不依靠积分进行排行的竞技场,只有当排名较低玩家战胜了排名较高玩家时,会交换双方排名。前者一次积分变化会导致较多的玩家排名发生变动,后者一次最多只会影响两名玩家的排名,但要考虑相同玩家同时被挑战的情况。

2.按照排行是否严格划分:并列排行榜允许积分相同的玩家处于同一名次,严格排行榜需要处理玩家相同积分情况下决定排名的规则。

此处我们只讨论积分排行榜。

积分排行榜的关键在于对于一个有序数据结构的维护更新,而对于该数据结构的实现主要有两种思路:

1.自己使用语言实现有序的数据结构

2.借助现成的工具,如MySQL,Redis实现有序排序

自己制定数据结构的方法

1.有序列表

按照积分大小将列表进行排序。

查询TopN:只需获取列表前TopN个元素,时间复杂度O(1)。

查询指定玩家排名:计算积分大于该玩家的人数,时间复杂度O(n)。

更新排名:玩家积分发生变化,需要将旧元素删除,把积分变化后的新元素插入列表中并进行重新排序,若使用快速排序,则时间复杂度为O(n²)。不过大多数情况下列表是基本有序的,比起对单纯打乱的列表进行排序会好很多。

排行榜较小,对效率没有极端要求的时候可以使用这种方法。

2.数组

构建大小为M的数值rank[],此时积分s对应的排名为rank[s]。

查询TopN:获取列表rank[1:N]的元素即可。

查询玩家自己排名:查询积分s对应的排名直接查询rank[s]即可,时间复杂度O(1)。

更新:若用户积分从s变为s+n,则把rank[s]到rank[s+n-1]这n个元素值加1即可,时间复杂度为O(n)。

很明显,游戏中排行榜积分相同的情况并不少见,引入桶可以解决积分相同的情况,但积分更新和查询玩家自身排行的策略需要改变,改变之后的策略可能并不比有序列表效率高。

3.平衡二叉树(AVL)

查询TopN:获取树的前N个元素即可,时间复杂度O(1)。

查询自己的排名:需要对数进行遍历,找出积分高于自己的玩家数量,时间复杂度O(n)。

更新:需要将原元素删除,将新元素插入树中,时间复杂度O(logn)。

4.跳表(skiplist)

跳表本质是可以实现二分查找的有序链表。

个人了解不深,直接给出参考文章:

https://yuerblog.cc/2019/02/13/skiplist-rank/

感觉在计算个人排名的时候效率会比平衡二叉树高,其他地方与平衡二叉树相差不大。

5.树形分区算法

详见

https://cloud.tencent.com/developer/article/1621522

本质是平衡二叉树,但与上面单纯使用平衡二叉树的方法不同,作者预先构建了一棵包含所有积分范围的树,树的每一层会根据范围划分,再将每一个需要统计排名的积分通过范围的比较放入树中,更新树的时候会更新每一层所包含的积分数量。当需要获取积分排名的时候,只需要获取每一层大于该积分的积分数量相加即可,时间复杂度可达到O(logn)。具体的实现方法建议直接进入文章查看。

使用现有工具的方法

1.使用SQL查询。

当数据量不大的时候可以直接使用数据库的查询。使用INSERT,UPDATE插入与更新玩家,使用SELECT COUNT查询分数高于某个玩家的人数,即是该玩家的排名。

好处是数据操作的细节被数据库隐藏了,在数量较少的时候能够提供方便的操作,缺点是当数据量大的时候,相较于操作放置于内存的数据结构,其性能会非常低下。

2.使用Redis的sorted set

其内部使用了Hash table和skip list,用来做排行榜有着天生的优势:提供了丰富的排行榜查询接口,例如zrank()用于查询指定元素的排名(下标),zrevrange()用于获取指定区间的元素。

3.使用Erlang有序异键形式(sorted set)的ETS

也有许多团队选择使用Erlang语言进行游戏开发,此时Erlang自带的ETS也是不错的选择。ETS的有序异键表是用平衡二叉树实现的。

一些需要考量的其他因素

排行榜可以定时更新,还是需要同步更新?

排行榜是严格排行榜是可以存在并列排名的排行榜?

如果是同步更新的严格排行榜,则需要自己制定在分数相同情况下的排行规则,一些 有着默认排行规则的排行榜用不了。

除此之外,需要进行排行的玩家数量也是很关键的因素,如果玩家数量不多,或者对于排行过低的玩家排名的准确性(甚至是是否展示排名)不做太强制的要求,除却上面的方法可能还有更适合的实现方式。

备忘参考:

海量用户积分排名算法探讨

https://www.cnblogs.com/weidagang2046/archive/2012/03/01/massive-user-ranking.html

游戏排行榜 – 基于skiplist计算rank排名

https://yuerblog.cc/2019/02/13/skiplist-rank/

在C#中使用二叉树实时计算海量用户积分排名的实现

https://cloud.tencent.com/developer/article/1621522

简单高效的排行榜算法——树状数组

https://www.owenzhang.net/blog/325.html

谈谈陌陌争霸在数据库方面踩过的坑(排行榜篇)

https://blog.codingnow.com/2014/03/mmzb_db_2.html

排行榜算法设计实现比较

https://gameinstitute.qq.com/community/detail/101951

使用Redis Zset来处理活动常用排行榜(精确排行)

https://segmentfault.com/a/1190000011737336

如何对游戏服务器全服玩家进行排名?

https://www.zhihu.com/question/27933771

海量用户的积分排序问题算法的分析

https://segmentfault.com/a/1190000004268386

开发笔记:基于积分的游戏排行榜实现方式探讨相关推荐

  1. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模(四) 粒子系统模拟(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7585937 作者:毛星云    邮箱: h ...

  2. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模 四 粒子系统模拟 一

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由zhm ...

  3. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模(四) 粒子系统模拟(一) .

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7585937 作者:毛星云    邮箱: h ...

  4. Egret实战开发笔记,飞行射击游戏(六)

    今天是开发飞行射击游戏第五天,玩家多类型子弹及状态和关卡模式. 简介 实现玩家特殊子弹,激光,追踪导弹. 玩家多状态 下方飞出 正常游戏 胜利等待 胜利飞出 以及 玩家保护 和 关卡切换 实现效果 本 ...

  5. Egret实战开发笔记,飞行射击游戏(二)

    简介 Egret实战开发,记录每天的学习进度,欢迎和我一起学习交流~ 目录 简介 实现目标 一.实现子弹类 二.工厂设计模式 三.子弹管理类ZDManager 实现目标 今天是开发飞行射击游戏第二天, ...

  6. 大学android移动开发笔记,基于Android的移动模拟练习系统的设计与实现

    李思莉 聂芝献 摘要:该文主要论述基于Android的移动模拟练习系统的功能设计及数据设计.数据实现.该系统客户端使用基于Android的移动应用开发技术,服务器端采用JAVA WEB+MySQL技术 ...

  7. iOS开发笔记--基于面向协议MVP模式下的软件设计

    传统模式下的开发 MVC MVVM 基于面向协议MVP的介绍 MVP实战开发 说在前面:  相信就算你是个iOS新手也应该听说过MVC的,MVC是构建iOS App的标准模板.随着时间的推移,在iOS ...

  8. 【游戏开发】基于MMORPG的游戏客户端逻辑效率开发思路

    思考:如何提升游戏逻辑开发效率 提升游戏逻辑开发效率的关键在于:游戏新增或修改功能时,需要尽可能减少程序需要重复开发的代码量. 下面主要考虑以下三种减少编码工作量的方法: <1>.尽可能将 ...

  9. IOS开发笔记 - 基于SDWebImage的网络图片加载处理

    前言: 在IOS下通过URL读一张网络图片并不像Asp.net那样可以直接把图片路径放到图片路径的位置就ok, 而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示. 这里找 ...

最新文章

  1. python是基于什么语言开发-2.python是什么编程语言。
  2. laravel中及其常用的一些函数方法(自己看)和技巧(不断添加中)
  3. (error) LOADING Redis is loading the dataset in memory问题解决
  4. matpython_[mcj]使用Matlab/Python合并mat文件并存为mat
  5. 中南民族大学c语言报告,中南民族大学信C语言实验报告.doc
  6. 基于PaddleRec的用户点击率预测
  7. linux ifconfig
  8. windows中端口号被占用的解决方法
  9. 技术实践丨体验量子神经网络在自然语言处理中的应用
  10. Activity生命周期Android,横屏切换不重新创建Activity, Activity的四种launchMode
  11. AcWing 852. spfa判断负环(spfa or bellman)
  12. 拓端tecdat|R语言自适应平滑样条回归分析
  13. 基于PHP的校园bbs论坛系统
  14. hackerrank Java Data Structures
  15. 伍斯特理工学院计算机科学硕士,美国伍斯特理工学院计算机科学硕士入学要求.pdf...
  16. ios 开发控件中心点_AppCan
  17. visio2019和Mathtype7.0版本冲突,出现VBE6EXT.OLB不能被加载
  18. 数据分析大数据面试题大杂烩01
  19. 最新校招笔试面试六十题
  20. 希捷160G 7200.10 8Mb硬盘辨真伪!

热门文章

  1. css3伪元素::_CSS荧光笔:使用:: selection伪选择器
  2. 运行超稳的散热风扇,机箱的百搭好伙伴,酷冷至尊Mobius120上手
  3. 实体店做网络营销的困惑
  4. 收取西联汇款最简单的方法
  5. HTML5大纲算法(HTML5 Outliner)
  6. openresty 操作 redis
  7. FindWindowEx使用方法
  8. 计算机性能的顶层提高空间很大:摩尔定律结束后,什么将推动计算机性能?
  9. SpringCloud之 Eureka注册中心
  10. centos7下设置vi的colorscheme