设计思路

客户端向服务器发送匹配请求,服务端接收后将客户端Session放入匹配队列中,匹配完成时通知用户。

使用观察者设计模式可以实现这个功能。

代码

观察者代码:

Java util 包拥有Observer 接口,这里根据实际应用自定义参数 Map。

import java.util.Map;

public interface Observer {

public void update(Map map);

}

被观察者接口:

import java.util.List;

public interface Observerable {

public void registerObserver(MatchNode o);

public void removeObserver(MatchNode o);

public void notifyObserver(List matchNodes);

}

匹配节点:

每个节点存放用户数据,用于进行匹配和查找。

import java.util.Map;

public class MatchNode implements Observer {

private Long userId;

private Long sessionId;

private Long ruleId;

public Long getUserId() {

return userId;

}

public void setUserId(Long userId) {

this.userId = userId;

}

public Long getSessionId() {

return sessionId;

}

public void setSessionId(Long sessionId) {

this.sessionId = sessionId;

}

public Long getRuleId() {

return ruleId;

}

public void setRuleId(Long ruleId) {

this.ruleId = ruleId;

}

@Override

public void update(Map map) {

}

}

匹配线程

使用被观察接口 registerObserver 和 registerObserver 可以对匹配队列中的用户进行管理,当匹配成功后,会将两个匹配成功的用户移除匹配集合,并对匹配成功的用户发送通知。

使用单例模式意味着可以在任意位置获取匹配线程的状态,在程序初始化时启动匹配线程即可。

用户在匹配成功时,由匹配线程生成一个 groupId 用于标记这对用户,可以通过groupId 在后续功能开发中可以起到查询的作用。

package common.thread;

import cn.hutool.core.util.IdUtil;

import common.util.RandomTable;

import lombok.extern.slf4j.Slf4j;

import java.util.*;

import java.util.stream.Collectors;

@Slf4j

public class MatchQueueThread implements Runnable, Observerable {

List matchNodes;

@Override

public void registerObserver(MatchNode o) {

matchNodes.add(o);

}

@Override

public void removeObserver(MatchNode o) {

if (!matchNodes.isEmpty())

matchNodes.remove(o);

}

@Override

public void notifyObserver(List matchNodes) {

//从匹配队列中移除

this.matchNodes.removeAll(matchNodes);

String groupId = IdUtil.randomUUID();

Map dataMap = new HashMap<>();

dataMap.put("groupId", groupId);

dataMap.put("tables", RandomTable.randomTableSerial());

matchNodes.forEach(matchNode -> {

matchNode.update(dataMap);

});

}

//单例

private static class SingletonClassInstance {

private static final MatchQueueThread instance = new MatchQueueThread();

}

private MatchQueueThread() {

matchNodes = new ArrayList<>();

}

public static MatchQueueThread getInstance() {

return SingletonClassInstance.instance;

}

public int getMatchCount() {

return matchNodes.size();

}

/**

* |

* 匹配逻辑

*/

@Override

public void run() {

Map> result = matchNodes.parallelStream()

.collect(Collectors.groupingBy(MatchNode::getRuleId));

for (Map.Entry> group : result.entrySet()) {

if (group.getValue().size() > 1) {

List matchNodes = group.getValue().subList(0, 2);

notifyObserver(matchNodes);

log.info("匹配成功 : " + matchNodes.get(0).getUserId() + " " + matchNodes.get(1).getUserId());

}

}

}

}

以上代码尚未经过实际运行测试。

java游戏房间匹配_游戏匹配实现相关推荐

  1. java游戏房间匹配_游戏匹配和结算实现

    匹配 匹配.png //请求匹配 message CM_Match { int type; //匹配房间类型 String name; //玩家名称 long targetPlayerId; //加入 ...

  2. java正则任意字符_正则表达式匹配任意字符(包括换行符)的写法

    今天在Java中想使用正则表达式来获取一段文本中的任意字符.于是很随意得就写出如下匹配规则: (.*) 结果运行之后才发现,无法获得换行之后的文本.于是查了一下手册,才发现正则表达式中,". ...

  3. python贪婪匹配和非贪婪匹配_贪婪匹配和非贪婪匹配

    1.什么是正则表达式的贪婪与非贪婪匹配 如:String str="abcaxc"; Patter p="ab*c"; 贪婪匹配:正则表达式一般趋向于最大长度匹 ...

  4. 买游戏来运营_游戏化思维帮你玩转社群运营

    传统的社群运营主要就是通过活动来进行运营的.但是如果只是单纯的通过各种活动,总是会造成只有过程,没有结果的情况,无法形成完整的运营体系. 今天,9妹跟大家来分享一下,怎么使用游戏化的思维,来更好的操作 ...

  5. 游戏开发论坛_游戏开发制作全流程介绍

    近日,根据<2020年1-6月中国游戏产业报告>显示,我国上半年网络游戏用户规模达到6.6亿人,游戏市场实际营收1394.93亿元,同比增长了22.34%,其中手游占比75.04%,达10 ...

  6. 古剑奇谭3服务器不稳定,古剑奇谭3设置游戏默认存档服务器方法_古剑奇谭3怎么修改游戏启动选项_游戏堡...

    < 修改启动选项: 一些玩家可能知道,Steam游戏可以自行设置游戏启动选项,已达到修改游戏设置.调整画面等目的. 本方法既通过设置游戏启动选项,来修改游戏默认连接服务器. 步骤: 在 Stea ...

  7. sword弹窗_刀剑神域夺命凶弹游戏问题解决方案汇总_刀剑神域夺命凶弹游戏出错怎么办_游戏堡...

    Hello,大家好!我是你们的老朋友Smile,<刀剑神域:夺命凶弹>已经在Steam平台发售一段日子了,但是很多玩家纷纷反映经常出现游戏错误,导致自己无法愉快的玩耍,那么这些问题如何才能 ...

  8. 3d游戏开发相关概念_游戏开发概念

    3d游戏开发相关概念 Game development is one of the most exciting fields of computer science and a major part ...

  9. 如何使用java编程算概率_游戏中概率的编程实现(转之别人)最简单的

    概率 听起来很玄 比如洗法宝 太一石 有一段说明 有一定概率 能改变法宝的技能阶数 那么 概率在编程中如何实现的呢 个人在大学里有学c++ java 以及vb 现以vb实现概率来说明 首先,要先说清楚 ...

最新文章

  1. 关于page object(PO)模型的介绍
  2. 如何完成从研究型到工程型的转变
  3. PHP统计网站pv(访问量)
  4. python实现vlookup功能_干货一:怎么在python里面实现vlookup
  5. vue+springboot-前台怎么回显本地文件夹下的图片
  6. Python基础概念_1_环境安装
  7. 前台特效(9)无限极分类折叠菜单
  8. Android10虚拟硬件,编辑 Android 虚拟设备属性
  9. 《大数据分析原理与实践》一一导读
  10. FPGA UART串口协议
  11. 怎样提高数据库查询效率
  12. 360Win10的360wifi无速度问题
  13. 验收测试的名词解释_验收测试工作流程及准则
  14. 商标注册计算机软件app属于第几类,软件商标属于第几类?
  15. 大数据扫黄,是怎样发现你的?
  16. ultraos win10启动盘_使用ultraiso软件制Win10专业版U盘系统盘制作安装教程
  17. python uniform 函数
  18. saber与matlab,saber与matlab的比较 (1)
  19. 毕业论文设计:第二部分—激光雷达里程计研究
  20. ARM汇编指令立即数规范和判断

热门文章

  1. Simulink电力电子仿真——(一)概述2
  2. vue高仿饿了么学习笔记(五)—— header 组件
  3. Google Earth Engine(GEE)——合并VCI指数和TCI温度得时序影像折线图(危地马拉、萨尔瓦多为例)
  4. 120年奥运会数据分析和可视化
  5. Gromacs g_mmpbsa结合能分析
  6. Android手机GNSS原始观测量
  7. 《密码与安全新技术专题》第六周作业
  8. 国产开源项目的七宗罪(转)
  9. 华为手机拆解:自研比重上升,硬件配置有惊喜!
  10. 外呼机器人起名_智能机器人外呼话术