游戏对战匹配逻辑小结
前言
近期接触了到了游戏后台的匹配逻辑,写此文作记录,也给后来者一些参考。
本文主要是对逻辑的一些整理,真正使用的时候还需根据实际场景来。
场景与需求
- 玩家去匹配战斗力与自己类似的其他玩家。如果在一定区间找不到对手,那就扩展区间。
- 连续匹配两次,不能匹配到相同的玩家。
- 如果已经战斗过的玩家,在一定时间内不能再被匹配到。(此处假设5分钟内不能再被匹配到,5分钟之后需要又可以被匹配到)
数据结构
根据上面几个需求,得出以下初步结论:
- 至少要有两个List,一个是可以匹配的玩家的List,另一个是已经战斗过的玩家的List。
- 由于需要根据不同战斗力来匹配不同的玩家,所以要根据不同战斗力,分出多个List。
- 需要随时可以获取到每个用户上次战斗的时间,这样才能让用户过了5分钟后又可以匹配到。
根据这三点,目前的结构是这样的:
//上次战斗的时间private final HashMap<String,Long> battleTimeMap=new HashMap<>();//不能战斗的队列private final LinkedList<String> unableBattleList=new LinkedList<>();//根据战力分区private final HashMap<Integer,LinkedList<String>> enableBattleMap=new HashMap<>();
匹配逻辑
已经可以确定是从一个List中选出被对战的玩家,选择的方式其实是两种:顺序读和随机读。
由于随机匹配两次,不能匹配到相同的玩家,所以随机读是很不方便的,于是就确定使用顺序读。
匹配的时候有一个场景的问题是必须解决的:
用户匹配到的对手,不一定会选择战斗,也可能直接退出匹配界面,或者换一个匹配的对手。
这时候,被匹配到,但却没有战斗过的用户仍应该在可被匹配的List中。
于是结构就变成了这样:
//上次战斗的时间private final HashMap<String,Long> battleTimeMap=new HashMap<>();//不能战斗的队列private final LinkedList<String> unableBattleList=new LinkedList<>();//根据战力分区private final HashMap<Integer,LinkedList<String>> enableBattleMap=new HashMap<>(); //是否可以被匹配private final HashSet<String> enableBattleSet=new HashSet<>();
添加了一个enableBattleSet,如果战斗过了,那么就不会在这个Set中。
于是逻辑就变成了这样:
- 匹配的时候,如果一个玩家被匹配到,首先看下是否enableBattleSet中,如果在,那么就返回,如果不在,那就把这个玩家移出匹配List,并且匹配下一个。
- 返回之后不移出可匹配的List,而是放到队列末尾。(因为只有战斗了才会被认为不能匹配)
- 在战斗开始后,将这个用户从enableBattleSet中移出。(这样在匹配的时候就不会被匹配到)
战斗冷却结束逻辑
简单来说就是将战斗冷却结束的用户放到可匹配的List中。
这个大概有两种实现方案:
- 由玩家每次匹配,触发战斗冷却结束的逻辑。
- 后来放一个线程,定时去触发战斗冷却技术的逻辑。
由于随着玩家越来越多,战斗匹配的逻辑触发会越发频繁。但是战斗冷却结束的逻辑没有必要那么频繁触发,所以方案一是不合适的。
笔者最终选择的是方案二。
上锁的逻辑
如果两个玩家战斗力类似,他们同时触发匹配的话,可能会匹配到同样的对手,这样就会导致被匹配到的玩家在同一时间与两个玩家战斗。这样显然是不合理的,所以需要对逻辑上锁。
上锁也是有两种方案:
- 对可匹配玩家的List上锁
- 对匹配函数上锁
两种方案笔者评估下都是可行的,都各有利弊:
- 对List上锁。
优势: 只有战斗力类似的玩家同时触发匹配逻辑才会阻塞,减小了由于“同时匹配”被阻塞的概率。
劣势: 如果在匹配的时候触发了“战斗冷却结束逻辑”,那么也会被阻塞,存在请求超时风险。 - 对匹配函数上锁
优势: 如果在匹配的时候触发了“战斗冷却结束逻辑”,不会被阻塞。而且结束战斗冷却的玩家是被放到List尾部,所以一般情况也不会影响匹配逻辑。
劣势: 所有玩家中,只要有有两个人同时触发匹配逻辑,就会有玩家被阻塞,存在请求超时风险。
一致性问题
实际操作过程中,一个服务一般都会部署在多台服务器上,这样才能通过负载均衡提高并发,并且在有一台服务器出故障的时候,能保证服务正常运行。
在这种情况下,匹配逻辑的中间过程就不能仅仅放在缓存中,而应该使用redis放在redis服务器上,这样才能保证匹配数据只有一份,而不是每台服务器都有一份。
游戏对战匹配逻辑小结相关推荐
- ios 棋类游戏对战的实现
棋类游戏对战的实现 六洲棋 五子棋 AI对战 蓝牙对战 在线对战 六洲棋 六洲棋,又称:泥棋.插方.来马.五福棋,中国民间传统棋类体育形式.源于民间,简便.通俗.易学,在民间广为流行,深受社会底层大众 ...
- 基于Qt的网络五子棋游戏对战
运行说明:先运行服务器,再运行客户端.输入房间号和昵称,会匹配到同一房间的人进行游戏对战. 软件下载:http://39.106.175.147/ftp/qtchess.exe 源码连接:http:/ ...
- html5 websocket 游戏,基于Websocket的H5在线游戏对战平台
基于Websocket的H5在线游戏对战平台 摘要 随着计算机的普及与互联网技术的发展,人们的生活方式发生了巨大的变化.基于B/S(Browser/Server)结构的系统不需要用户安装客户端软件,它 ...
- 【Lyra UI】UI 玩法逻辑小结
[Lyra UI]UI 玩法逻辑小结 UI 这块分两个部分:功能版逻辑 + 材质效果 本篇讨论逻辑,即怎么组织UI结构,代码怎么串联事件和逻辑 笔者之前并没有用UE开发过游戏,也算是从零开始,所以并不 ...
- 泡泡游戏获数百万美元Pre-A轮融资,打造AI加持的小游戏对战平台
10月9日消息,微信小游戏平台「泡泡游戏」(公司为杭州泡泡游戏网络科技有限公司)已于6 月完成数百万美元Pre-A 轮融资,本轮由 启明创投独家出资,回音资本担任融资顾问.今年2 月,泡泡游戏曾获腾讯 ...
- C#开发Unity游戏教程之游戏对象的行为逻辑方法
C#开发Unity游戏教程之游戏对象的行为逻辑方法 游戏对象的行为逻辑--方法 方法(method),读者在第1章新建脚本时就见过了,而且在第2章对脚本做整体上的介绍时也介绍过,那么上一章呢,尽管主要 ...
- Data Modle:游戏对战模型
仿真:游戏对战模型 1- Hero 性别 名字 性格-非理性度 认知-理性度 经验 等级 悟性 血量 攻击力 防御力 行走速度 视野范围 装备 天赋技能 金钱 位置 2- 模型 a- 自由行走模型 X ...
- Java简易版的对战小游戏(主题是三国类游戏对战)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 提示:今天写一个简易版的Java对战小游戏(主题是三国类游戏对战): 需要先写一个Person类(代表人),然后写一个 ...
- 利用 Proxy 代理与 Reflect 反射实现 mv 模型视图,实现一个 打怪升级 的小游戏“勇士之战”
利用 Proxy 代理与 Reflect 反射实现 mv 模型视图,多层数据动态渲染页面,模仿 vue3 双向绑定中 viewModel 核心功能,实现一个 打怪升级 的小游戏"勇士之战&q ...
最新文章
- linux hadoop etc目录,题目Linux平台下Hadoop的安装配置
- linux ftp服务
- 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
- python求定积分的函数_手搓计算化学(GTO积分by python)
- Hadoop搭建集群中输入hdfs namenode -format格式化节点时,提示:hdfs: command not found 解决办法
- suse 9 图形安装出现4画面
- 内存超频时序怎么调_电脑内存条专业科普,内存选购、内存品牌、内存安装、内存时序体质、内存超频频率详细讲解...
- quartz集成到springboot_一个用来学习 spring boot 的开源项目,总共包含 57 个集成demo...
- Linux复习-C程序编译工具
- 《Redis开发与运维》学习第五章
- 本科毕设研究记录(一)————小样本综述
- 计算机一级考试创建快捷方式,九月计算机一级MSOffice考试试题
- 泛微OA使用笔记-架构
- outlook导入服务器邮件,OUTLOOK怎么导入邮件?
- java发送图片邮件_使用javamail发送包含图片的html格式邮件详解
- Android 模拟屏幕点击和物理按键方式
- 微软量子论文撤稿,谷歌“量子霸权”受质疑,量子计算的狂热需一盆冷水清静
- k-means算法进行员工培训方向分组
- debian linux iso下载工具,debian 8.7系统下载
- 2018首届传神者大会:“语言+新技术”将推动语言产业生态化发展 2018首届传神者大会圆满落幕,“语言+新技术”或开启全球深度互联时代 智联未来,跨界赋能 1211首届传神者大会圆满落幕...