匹配规则:

上一场次胜:匹配优先级(胜>平>负>已匹配过的对手)

上一场次负:匹配优先级(平>负>胜>已匹配过的对手)

上一场次平:匹配优先级(胜平负>已匹配过的对手)

实现思路:

将玩家根据上一场次胜负情况将玩家分为胜、平、负、三个池子,优先匹配胜者池中的选手,匹配每一个选手时将改玩家已经对阵过的选手排除掉,然后根据匹配优先级从对应池中选出合适的选手进行匹配,匹配成功后需要将玩家从对应的池中删除掉,再进行下一玩家的匹配,最后如果:胜平负三轮匹配完成后仍有未匹配的玩家,则将剩余玩家进行随机匹配

代码实现:


import cn.hutool.core.util.IdUtil;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** 双人游戏玩家匹配*/
public class TwoPlayerPickSolution {public static void main(String[] args) {pick();}/*** 匹配*/private static void pick(){//胜者池List<Integer> collectWin = new ArrayList<>();for (int i=0;i<1000;i++){collectWin.add(i);}//败者池List<Integer> collectLoss = new ArrayList<>();for(int i=10000;i<11000;i++){collectLoss.add(i);}//平者池List<Integer> collectTie = new ArrayList<>();for(int i=100000;i<101000;i++){collectTie.add(i);}//匹配胜者池Map<String,List<Integer>> winMap = handlerWinPool(collectWin, collectLoss, collectTie);List<Integer> winLeftUsers = winMap.get("left");List<Integer> winList = winMap.get("win");List<Integer> lossList = winMap.get("loss");List<Integer> tieList = winMap.get("tie");collectWin.removeAll(winList);collectLoss.removeAll(lossList);collectTie.removeAll(tieList);//匹配败者池Map<String,List<Integer>> lossMap = handlerLossPool(collectWin, collectLoss, collectTie);List<Integer> lossLeftUsers = lossMap.get("left");List<Integer> winList2 = lossMap.get("win");List<Integer> lossList2 = lossMap.get("loss");List<Integer> tieList2 = lossMap.get("tie");collectWin.removeAll(winList2);collectLoss.removeAll(lossList2);collectTie.removeAll(tieList2);//匹配平者池Map<String,List<Integer>> tieMap = handlerTiePool(collectWin, collectLoss, collectTie);List<Integer> tieLeftUsers = tieMap.get("left");List<Integer> winList3 = tieMap.get("win");List<Integer> lossList3 = tieMap.get("loss");List<Integer> tieList3 = tieMap.get("tie");collectWin.removeAll(winList3);collectLoss.removeAll(lossList3);collectTie.removeAll(tieList3);//最低优先级匹配List<Integer> leftUsers = Stream.of(winLeftUsers, lossLeftUsers, tieLeftUsers).flatMap(Collection::stream).collect(Collectors.toList());handlerLeftUser(leftUsers);}/*** 胜者池匹配* @param collectWin 胜者池* @param collectLoss 败者池* @param collectTie 平者池*/private static Map<String,List<Integer>> handlerWinPool(List<Integer> collectWin,List<Integer> collectLoss,List<Integer> collectTie) {List<Integer> leftUsers = new ArrayList<>();List<Integer> winList = new ArrayList<>();List<Integer> lossList = new ArrayList<>();List<Integer> tieList = new ArrayList<>();while (collectWin.size()>0) {Integer currentUserId = collectWin.get(0);winList.add(currentUserId);//获取当前用户已经匹配过的选手集合(此处为空集合,可从db,rds或其他存储引擎获取)Set<Integer> pickedUsers = new HashSet<>();pickedUsers.add(currentUserId);//排除当前玩家已经匹配过的用户List<Integer> winCanSelects = collectionFilter(collectWin,pickedUsers);List<Integer> lossCanSelects = collectionFilter(collectLoss,pickedUsers);List<Integer> tieCanSelects = collectionFilter(collectTie,pickedUsers);if (winCanSelects.size() > 0) {//匹配成功Integer pickUserId = handlerPickSuccess( currentUserId, winCanSelects);collectWin.remove(currentUserId);collectWin.remove(pickUserId);winList.add(pickUserId);}else if (tieCanSelects.size()>0){Integer pickUserId = handlerPickSuccess(currentUserId,tieCanSelects);collectWin.remove(currentUserId);collectTie.remove(pickUserId);tieList.add(pickUserId);} else if (lossCanSelects.size()>0) {Integer pickUserId = handlerPickSuccess(currentUserId,lossCanSelects);collectWin.remove(currentUserId);collectLoss.remove(pickUserId);lossList.add(pickUserId);} else {collectWin.remove(currentUserId);leftUsers.add(currentUserId);}}Map<String,List<Integer>> map = new HashMap<>();map.put("win",winList);map.put("loss",lossList);map.put("tie",tieList);map.put("left",leftUsers);return map;}/*** 败者池匹配* @param collectWin 胜者池* @param collectLoss 败者池* @param collectTie 平者池*/private static Map<String,List<Integer>> handlerLossPool(List<Integer> collectWin,List<Integer> collectLoss,List<Integer> collectTie) {List<Integer> leftUsers = new ArrayList<>();List<Integer> winList = new ArrayList<>();List<Integer> lossList = new ArrayList<>();List<Integer> tieList = new ArrayList<>();while (collectLoss.size()>0) {Integer currentUserId = collectLoss.get(0);lossList.add(currentUserId);//获取当前用户已经匹配过的选手集合Set<Integer> pickedUsers = new HashSet<>();pickedUsers.add(currentUserId);List<Integer> winCanSelects = collectionFilter(collectWin,pickedUsers);//排除当前用户已经匹配过的选手List<Integer> lossCanSelects = collectionFilter(collectLoss,pickedUsers);List<Integer> tieCanSelects = collectionFilter(collectTie,pickedUsers);if (tieCanSelects.size()>0){Integer pickUserId = handlerPickSuccess(currentUserId,tieCanSelects);collectLoss.remove(currentUserId);collectTie.remove(pickUserId);tieList.add(pickUserId);} else if (lossCanSelects.size()>0) {Integer pickUserId = handlerPickSuccess(currentUserId,lossCanSelects);collectLoss.remove(currentUserId);collectLoss.remove(pickUserId);lossList.add(pickUserId);} else {collectLoss.remove(currentUserId);leftUsers.add(currentUserId);}}Map<String,List<Integer>> map = new HashMap<>();map.put("win",winList);map.put("loss",lossList);map.put("tie",tieList);map.put("left",leftUsers);return map;}/*** 平者池匹配* @param collectWin 胜者池* @param collectLoss 败者池* @param collectTie 平者池*/private static Map<String,List<Integer>> handlerTiePool(List<Integer> collectWin,List<Integer> collectLoss,List<Integer> collectTie) {List<Integer> leftUsers = new ArrayList<>();List<Integer> winList = new ArrayList<>();List<Integer> lossList = new ArrayList<>();List<Integer> tieList = new ArrayList<>();while (collectTie.size()>0) {Integer currentUserId = collectTie.get(0);tieList.add(currentUserId);//获取当前用户已经匹配过的选手集合Set<Integer> pickedUsers = new HashSet<>();pickedUsers.add(currentUserId);
//            List<Integer> winCanSelects = collectionFilter(collectWin,pickedUsers);//排除当前用户已经匹配过的选手List<Integer> lossCanSelects = collectionFilter(collectLoss,pickedUsers);List<Integer> tieCanSelects = collectionFilter(collectTie,pickedUsers);if (tieCanSelects.size()>0){Integer pickUserId = handlerPickSuccess(currentUserId,tieCanSelects);collectTie.remove(currentUserId);collectTie.remove(pickUserId);tieList.add(pickUserId);} else if (lossCanSelects.size()>0) {Integer pickUserId = handlerPickSuccess(currentUserId,lossCanSelects);collectTie.remove(currentUserId);collectLoss.remove(pickUserId);lossList.add(pickUserId);} else {collectTie.remove(currentUserId);leftUsers.add(currentUserId);}}Map<String,List<Integer>> map = new HashMap<>();map.put("win",winList);map.put("loss",lossList);map.put("tie",tieList);map.put("left",leftUsers);return map;}/*** 匹配成功处理* @param currentUserId* @param winCanSelects*/private static Integer handlerPickSuccess(Integer currentUserId, List<Integer> winCanSelects) {Integer pickUserId = winCanSelects.get(0);long sessionId = IdUtil.getSnowflakeNextId();System.out.println("匹配成功:currentUserId=" + currentUserId + ",pickUserId=" + pickUserId + ",sessionId=" + sessionId);return pickUserId;}/*** 匹配剩余选手(最低优先级匹配)* @param users*/private static void handlerLeftUser(List<Integer> users){if(null != users && users.size()>0){int size = users.size();for(int i=0;i<size/2;i++){int currentUserId = users.get(i);int pickUserId = users.get(size-1-i);long sessionId = IdUtil.getSnowflakeNextId();System.out.println("匹配成功:currentUserId=" + currentUserId + ",pickUserId=" + pickUserId + ",sessionId=" + sessionId);}}}public static <T> List<T> collectionFilter(List<T> list,Set<T> list2){List<T> result = new ArrayList<>();for(int i=0;i<list.size();i++){T t = list.get(i);if(!list2.contains(t)){result.add(t);}}return result;}
}

总结:

个人觉得以上算法效率仍有可以改进的空间,希望各位博友能提出有效的改进方案

双人游戏根据胜负关系匹配相关推荐

  1. AAAI 2021 | 从语义关系建模的角度进行句子语义关系匹配

    ©PaperWeekly 原创 · 作者|张琨 学校|中国科学技术大学博士生 研究方向|自然语言处理 论文标题: Making the Relation Matters: Relation of Re ...

  2. ACL 2019 | 图表示解决长文本关系匹配问题:腾讯提出概念交互图算法

    本文作者:Bang Liu.Di Niu等 文章之间关系匹配是自然语言处理领域的重要问题.传统算法忽略了文本内部语义结构,而深度神经网络目前主要用于句子对之间的匹配.同时由于长文本对计算量需求较大,且 ...

  3. 名字测试匹配度软件,姓名测试缘分配对:测试两人关系匹配度是怎样的

    根据姓名音韵测试爱情 一个吉祥的名字,对一个人的健康.婚姻.事业有极强的灵动力和暗示力,增进人与社会的和谐相处,这次想跟大家介绍如何根据姓名音韵测试爱情,接着往下看吧 根据姓名音韵测试爱情的具体方法 ...

  4. xpath的数据和节点类型以及XPath中节点匹配的基本方法

    XPath数据类型  XPath可分为四种数据类型:  节点集(node-set)  节点集是通过路径匹配返回的符合条件的一组节点的集合.其它类型的数据不能转换为节点集.  布尔值(boolean)  ...

  5. 程序设计——第七周作业(Floyd:胜负未知场数;dijkstra:猫猫快线最快线路;SPFA:城市收税)

    A-胜负未知场数 题目描述 众所周知,TT 有一只魔法猫. 这一天,TT 正在专心致志地玩<猫和老鼠>游戏,然而比赛还没开始,聪明的魔法猫便告诉了 TT 比赛的最终结果.TT 非常诧异,不 ...

  6. 图的匹配---图论笔记

    图的匹配 – 潘登同学的图论笔记 文章目录 图的匹配 -- 潘登同学的图论笔记 独立数和支配数的关系 匹配 边覆盖 `柯尼希给出:二部图中匹配数和最小点覆盖数的相等关系` 二部图的匹配 顶点支配,独立 ...

  7. LARS算法探究LOL比赛各数据对胜负的影响

    昨天搞完二叉决策树刷了一会儿玩加赛事,发现他们给出了lck,eu,na和入围赛的数据,刚好最近刚学完惩罚线性回归机器学习模型,就着手打算一边学着书上的模型一边用这个职业赛场的数据看看lol比赛背后的输 ...

  8. 关于flask入门教程-ajax+echarts实现关系图

    关系图,从字面上可以看出,为关系的图形,既然为关系,那么就需要有点以及关系,用来表示点与点之间的联系.所以我们可以得出:关系图需要两个必要的元素,节点,关系,其中关系需要包含有联系的节点以及节点联系说 ...

  9. 【CIKM 2020】基于多视图协作学习的人岗匹配研究

    点击上方,选择星标或置顶,每天给你送干货! 阅读大概需要16分钟 跟随小博主,每天进步一丢丢 来自:RUC AI BOX 近日,第29届国际计算机学会信息与知识管理大会(CIKM 2020)在线上召开 ...

  10. ICCV2013: 亲属关系预测 Facial Expression Dynamics for Kinship Verification 学习笔记

    Dance with Flow: Two-in-One Stream Action Detection 学习时,别忘了总是要问自己一个为什么 论文 文章: Like Father, Like Son: ...

最新文章

  1. 2018-3-2线性表
  2. 清华大学施路平:双脑驱动的人工通用智能
  3. 使用英伟达NeMo让你的文字会说话,零基础即可实现自然语音生成任务 | 附代码...
  4. python reshape transpose
  5. 【Groovy】循环控制 ( Number 注入函数实现循环 | times 函数 | upto 函数 | downto 函数 | step 函数 | 闭包作为最后参数可写在外面 )
  6. 声明式事务--@EnableTransactionManagement || @Transactional
  7. (原创).Net将EF运用于Oralce一 准备工作
  8. 【Linux网络编程】TCP三次握手和四次挥手
  9. 在java中使用ffmpeg将amr格式的语音转为mp3格式
  10. 【MSP是什么】最佳管理实践指南
  11. arm开发板挂载win10和ubuntu haneWIN NFS Server
  12. 需求跟踪矩阵(Requirement Tracking Matrix)
  13. Python实现键盘操作方法
  14. 杂谈-苹果账号调查事件始末,Apple审核流程或有变
  15. win7桌面上的ie图标删不掉怎么办
  16. 【预定义】C语言预定义代码(宏、条件编译等)内容介绍【最全的保姆级别教程】
  17. 数据结构 队列顺序储存 医院叫号系统
  18. 保研英语自我介绍计算机,计算机保研面试英文自我介绍
  19. 服务器开机一进系统就黑屏,win7系统开机在欢迎界面直接黑屏怎么办
  20. PAL和NTSC有什么区别

热门文章

  1. java jsonp网络爬虫_JSOUP 爬虫
  2. robocode 安装 使用
  3. 操作系统 - 调度算法(高响应比优先算法)
  4. 社区团购微信小程序开发
  5. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(6)- Bootable image格式与加载(elftosb/.bd)...
  6. EndNote X9导入论文投稿的期刊参考文献格式
  7. 商业云平台和开源云平台
  8. matlab 拟合函数 调用,matlab拟合函数
  9. 60、在Visual Studio 2019 环境下,使用C#调用C++生成的dll实现yolov5的图片检测
  10. oracle instant imp,使用instantclient连接oracle数据库