当前位置: 首页 > news >正文

[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

文章目录

  • 创建房间类
    • 创建房间类
    • 实现房间管理器
  • 实现匹配器(3)
  • 验证匹配功能
    • 问题:匹配按钮不改变
    • 验证多开
  • 小结

创建房间类

LOL,通过匹配的方式,自动给你加入到一个房间,也可手动创建游戏房间

  • 这一局游戏,进行的“场所”就可以称为是一个“游戏房间”,游戏房间中最关键的信息,就是玩家信息
  • 一个游戏服务器,有同时存在了多个游戏房间

我们就需要一个“游戏房间管理器”来管理多个游戏房间image.png|429

  • 键值对的方式,给每个 room 生成一个唯一的 roomId,以键值对 (哈希表) 在 room manager 中来进行管理

创建房间类

匹配成功之后,需要把对战的两个玩家放到同一个房间对象中

创建 game.Room

  • 一个房间要包含一个房间 ID,使用 UUID 做为房间的唯一身份标识
  • 房间内要记录对弈的玩家双方信息

UUID 表示“世界上唯一的身份标识”

  • 通过一系列的算法,能够生成一串字符串(一组十六进制表示的数字)
  • 两次/任意次调用这个算法,生产的这个字符串都是不同的
package org.example.java_gobang.game;  import org.example.java_gobang.model.User;  import java.util.UUID;  // 表示一个游戏房间  
public class Room {  // 此处我们使用字符串的类型来表示,方便生成唯一值  private String roomId;  private User user1;  private User user2;  public String getRoomId() {  return roomId;  }  public void setRoomId(String roomId) {  this.roomId = roomId;  }  public User getUser1() {  return user1;  }  public void setUser1(User user1) {  this.user1 = user1;  }  public User getUser2() {  return user2;  }  public void setUser2(User user2) {  this.user2 = user2;  }  public Room() {  // 构造 Room 的时候,生成一个唯一的字符串来表示房间 id        roomId = UUID.randomUUID().toString();  }  
}

实现房间管理器

Room 对象会存在很多,每两个对弈的玩家,都对应一个 Room 对象,需要创建一个管理器对象来管理所有的 Room

创建 game.RoomManager

  • 使用一个 Hash 表,保存所有房间对象
    • key:roomId
    • value:Room对象
  • 再使用一个 Hash 表,保存 userId -> RoomId 的映射,方便根据玩家来查找所在的房间
  • 提供增、删、查的 API
    • 查询包含基于房间 ID 的查询和基于用户 ID 的查询
package org.example.java_gobang.game;  import org.springframework.stereotype.Component;  import java.util.concurrent.ConcurrentHashMap;  // 房间管理器,这个类也希望有唯一实例  
@Component  
public class RoomManager {  private ConcurrentHashMap<String, Room> rooms = new ConcurrentHashMap<>();  // 通过这个哈希表,把玩家和房间之间的关系维护起来  private ConcurrentHashMap<Integer, String> userIdToRoomId = new ConcurrentHashMap<>();  public void add(Room room, int userId1, int userId2) {  rooms.put(room.getRoomId(), room);  userIdToRoomId.put(userId1, room.getRoomId());  userIdToRoomId.put(userId2, room.getRoomId());  }  public void remove(String roomId, int userId1, int userId2) {  rooms.remove(roomId);  userIdToRoomId.remove(userId1);  userIdToRoomId.remove(userId2);  }  public Room getRoomByRoomId(String roomId) {  return rooms.get(roomId);  }  // 根据用户id 定位房间  public Room getRoomByUserId(int userId) {  String roomId = userIdToRoomId.get(userId);  if(roomId == null) {  // userId -> roomId 映射关系不存在,直接返回 null            return null;  }  return rooms.get(roomId);  }  
}

实现匹配器(3)

完善刚才匹配逻辑中的 TODO,并把玩家放到一个房间中 image.png|353

  • 先给 Matcher 注入 RoomManager 对象
@Component
public class Matcher {//......// 房间管理器@Autowiredprivate RoomManager roomManager;// ......
}然后修改 Matcher.handlerMatch,补完之前 TODO 的内容
private void handlerMatch(Queue<User> matchQueue) {// 4. 把这两个玩家放到一个游戏房间中  Room room = new Room();  roomManager.add(room, player1.getUserId(), player2.getUserId());// ......
}

验证匹配功能

问题:匹配按钮不改变

当前发现,玩家点击匹配之后,匹配按钮的文本不发生改变

  • 分析之前写的代码,点击按钮的时候,仅仅是给服务器发送了一个 websocket 请求,告诉服务器我要开始匹配了
  • 服务器会立即返回一个响应,“进入匹配队列成功”,然后页面再修改按钮的文本image.png|372

出现问题的原因:

  • 服务器在处理匹配请求的时候,按理说是要立即就返回一个 websocket 响应的
  • 实际上在服务器代码这里构造了响应对象,但是忘记 sendMessage,给发回去了image.png|338
    在红框中加入如下逻辑代码
// 将 response 先转换成 JSON 字符串,然后将其通过 sendMessage 发回客户端  
String jsonString = objectMapper.writeValueAsString(response);  
session.sendMessage(new TextMessage(jsonString));

就类似于:你网购买了个东西,商家都已经打包好了,但是最后忘记发货了

image.png

验证匹配功能的时候,模拟多个用户登录的情况,最好使用多个浏览器,避免同一个浏览器中的 cookie/session 信息互相干扰

  • 如果只有一个浏览器,并且是 chrome 的话,chrome 有个无痕模式(不会记录历史记录,也不会记录 cookie,页面关闭的时候会自动清空)

验证多开

当我们打开两个页面,登录同一个账号的时候,后登录的页面的检查页面会出现提示,但是正常用户多开了在页面中却没有显示 image.png

  • 当用户多开之后,连接就会直接关闭,不能再进行匹配了image.png
    image.png|449

当前情况下,防多开机制起到了作用,但是又感觉差了点意思

  • 要是在第二个账号登录的时候,在页面中直接有提示就更好了

此时我们就可以调整前端代码,当检测到多开的时候,就给用户一个更加明确的提示 image.png|422

这样,在我们登录的时候,要是出现了多开的情况,就直接报错了,返回重新登录页面image.png|492

  • 当我们修改了 css 样式/ JS 文件之后,往往要在浏览器中使用 cmd+shift+R(Windows:ctrl+f5)强制刷新,才能生效
  • 否则浏览器可能仍然在执行旧版本的代码(浏览器自带缓存)

小结

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相关文章:

  • Python打卡训练营Day40
  • 《 PyTorch 2.3革新:torch.compile自动生成CUDA优化内核全解》
  • 使用 SymPy 操作三维向量的反对称矩阵
  • 树莓派安装openwrt搭建软路由(ImmortalWrt固件方案)
  • 历年厦门大学计算机保研上机真题
  • Prevent this information from being displayed to the user 修复方案
  • day14 leetcode-hot100-26(链表5)
  • vscode实时预览编辑markdown
  • Java Spring Boot 自定义注解详解与实践
  • Camera相机人脸识别系列专题分析之六:MTK ISP6S平台人脸识别fdnode流程FdNodeImp.cpp详解
  • 历年四川大学计算机保研上机真题
  • rm删除到回收站
  • RustDesk 搭建自建服务器并设置服务自启动
  • deepseek问答记录:请讲解一下torch.full_like()
  • 大数据量下的数据修复与回写Spark on Hive 的大数据量主键冲突排查:COUNT(DISTINCT) 的陷阱
  • 基本数据指针的解读-C++
  • Visual Studio中的宏变量
  • Python打卡训练营day40——2025.05.30
  • 每日算法 -【Swift 算法】将整数转换为罗马数字
  • JS手写代码篇---手写节流函数
  • 小企业网站建设多少钱/青岛网站制作
  • b2b网站大全专线软件开发/长尾关键词是什么意思
  • 乐清网站只做/最新足球新闻头条
  • 网站做一样没有侵权吧/发布项目信息的平台
  • 推文最好的网站是哪个/太原网站建设谁家好
  • 互利互通网站建设/成都网站建设软件