[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结
文章目录
- 创建房间类
- 创建房间类
- 实现房间管理器
- 实现匹配器(3)
- 验证匹配功能
- 问题:匹配按钮不改变
- 验证多开
- 小结
创建房间类
LOL,通过匹配的方式,自动给你加入到一个房间,也可手动创建游戏房间
- 这一局游戏,进行的“场所”就可以称为是一个“游戏房间”,游戏房间中最关键的信息,就是玩家信息
- 一个游戏服务器,有同时存在了多个游戏房间
- 键值对的方式,给每个 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 rooms = new ConcurrentHashMap(); // 通过这个哈希表,把玩家和房间之间的关系维护起来 private ConcurrentHashMap 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)
- 先给 Matcher 注入 RoomManager 对象
@Component public class Matcher { //...... // 房间管理器 @Autowired private RoomManager roomManager; // ...... } 然后修改 Matcher.handlerMatch,补完之前 TODO 的内容 private void handlerMatch(Queue matchQueue) { // 4. 把这两个玩家放到一个游戏房间中 Room room = new Room(); roomManager.add(room, player1.getUserId(), player2.getUserId()); // ...... }
验证匹配功能
问题:匹配按钮不改变
当前发现,玩家点击匹配之后,匹配按钮的文本不发生改变
- 分析之前写的代码,点击按钮的时候,仅仅是给服务器发送了一个 websocket 请求,告诉服务器我要开始匹配了
- 服务器会立即返回一个响应,“进入匹配队列成功”,然后页面再修改按钮的文本
出现问题的原因:
- 服务器在处理匹配请求的时候,按理说是要立即就返回一个 websocket 响应的
- 实际上在服务器代码这里构造了响应对象,但是忘记 sendMessage,给发回去了
在红框中加入如下逻辑代码
// 将 response 先转换成 JSON 字符串,然后将其通过 sendMessage 发回客户端 String jsonString = objectMapper.writeValueAsString(response); session.sendMessage(new TextMessage(jsonString));
就类似于:你网购买了个东西,商家都已经打包好了,但是最后忘记发货了
验证匹配功能的时候,模拟多个用户登录的情况,最好使用多个浏览器,避免同一个浏览器中的 cookie/session 信息互相干扰
- 如果只有一个浏览器,并且是 chrome 的话,chrome 有个无痕模式(不会记录历史记录,也不会记录 cookie,页面关闭的时候会自动清空)
验证多开
- 如果只有一个浏览器,并且是 chrome 的话,chrome 有个无痕模式(不会记录历史记录,也不会记录 cookie,页面关闭的时候会自动清空)
- 先给 Matcher 注入 RoomManager 对象
- 查询包含基于房间 ID 的查询和基于用户 ID 的查询
- 使用一个 Hash 表,保存所有房间对象
- 键值对的方式,给每个 room 生成一个唯一的 roomId,以键值对 (哈希表) 在 room manager 中来进行管理
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。