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

news2025/6/1 22:46:57

文章目录

  • 创建房间类
    • 创建房间类
    • 实现房间管理器
  • 实现匹配器(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 {
	//......

	// 房间管理器
	@Autowired
	private 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)强制刷新,才能生效
  • 否则浏览器可能仍然在执行旧版本的代码(浏览器自带缓存)

小结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2392995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实验设计与分析(第6版,Montgomery)第3章单因子实验:方差分析3.11思考题3.7 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第3章单因子实验&#xff1a;方差分析3.11思考题3.7 R语言解题。主要涉及单因子方差分析&#xff0c;正态性假设检验&#xff0c;残差与拟合值的关系图&#xff0c;平方根变换。 X<-c(…

【知识点】第2章:Python程序实例解析

文章目录 知识点整理Python程序语法元素分析 练习题判断题填空题选择题 知识点整理 Python程序语法元素分析 Python程序包括格式框架、注释、变量、表达式、分支语句、循环语句、函数等语法元素。 程序的格式框架 Python语言采用严格的 “缩进” 来表明程序的格式框架。缩进…

每日Prompt:指尖做画

提示词 微缩景观&#xff0c;微距摄影&#xff0c;俯瞰角度&#xff0c;特写&#xff0c;硕大食指手指甲&#xff0c;一个小小的人正在做画&#xff0c;小人右手拿画笔&#xff0c;小人左手拿调色盘&#xff0c;在指甲上作画&#xff0c;画的是中国古代山水画&#xff0c;背景…

redis未授权(CVE-2022-0543)

概述 Redis 默认绑定在 0.0.0.0:6379&#xff0c;在未配置防火墙或访问控制的情况下会将服务暴露在公网上。若未设置访问密码&#xff08;默认通常为空&#xff09;&#xff0c;攻击者可直接未授权访问 Redis。利用 Redis 提供的 CONFIG 命令&#xff0c;攻击者可修改配置并将…

【运维实战】Linux 中su和sudo之间的区别以及如何配置sudo!

Linux 系统相比其他操作系统具有更高的安全性&#xff0c;其安全机制的核心之一在于用户管理策略和权限控制--普通用户默认无权执行任何系统级操作。 若普通用户需要进行系统级变更&#xff0c;必须通过su或sudo命令提权。 1.su与sudo的本质区别 su 要求直接共享 root 密码&…

浏览器之禁止打开控制台【F12】

前言 在有时我们的日常开发工作中&#xff0c;有些项目要求我们增加禁用控制台的要求&#xff0c;这种虽然很鸡肋&#xff0c;但是它确实存在&#xff0c;并且会让哈哈心里觉得很有成就感。 所以今天他来了。 文章目录 前言无限debugger实现思路&#xff1a;效果如下&#xff1…

GEARS以及与基础模型结合

理解基因扰动的反应是众多生物医学应用的核心。然而&#xff0c;可能的多基因扰动组合数量呈指数级增长&#xff0c;严重限制了实验探究的范围。在此&#xff0c;图增强基因激活与抑制模拟器&#xff08;GEARS&#xff09;&#xff0c;将深度学习与基因-基因关系知识图谱相结合…

计算机网络 | 1.1 计算机网络概述思维导图

附大纲&#xff1a; 计算机网络的概念 一个通过通信设备与线路把不同计算机系统连接起来&#xff0c;实现资源共享和信息传递的系统 计算机网络的组成 从组成成分上 硬件&#xff1a;主机、通信链路、交换设备、通信处理机软件&#xff1a;网络操作系统、聊天软件等协议&…

最悉心的指导教程——阿里云创建ECS实例教程+Vue+Django前后端的服务器部署(通过宝塔面板)

各位看官老爷们&#xff0c;点击关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 阿里云创建ECS实例教程 注意&#xff1a; 阿里云有300元额度的免费适用期哟 白嫖~~~~ 注册了阿里云账户后&#x…

windows中Redis、MySQL 和 Elasticsearch启动并正确监听指定端口

Redis&#xff1a;在 localhost 上启动&#xff0c;并监听端口 6379 MySQL&#xff1a;在 localhost 上启动&#xff0c;并监听端口 3306 Elasticsearch&#xff1a;在 127.0.0.1 上启动&#xff0c;并监听端口 9300 1. Redis 确保 Redis 在 localhost 上启动并监听端口 6379…

学者观察 | Web3.0的技术革新与挑战——北京理工大学教授沈蒙

导语 沈蒙老师认为Web3.0正推动形成新型数据基础设施架构和数据要素流通机制&#xff0c;有望在数字经济时代发挥重要作用&#xff0c;对我国经济发展和社会进步将产生深远影响。AI在推动Web3.0发展方面具有巨大的潜力&#xff0c;但在隐私保护、公平性与安全性等方面也存在“…

pycharm终端遇不显示虚拟环境的问题

大部分我们用pycharm会配合我们的anaconda来使用&#xff0c;但是配置好后&#xff0c;可能会出现pycharm终端不显示虚拟环境的问题。 首先是确定不显示环境&#xff0c;下图中如果没有这个方框&#xff0c;就是不显示虚拟环境。此时用pip或者conda的命令是会提示不是 “不是内…

聊聊网络变压器的浪涌等级标准是怎样划分的呢?

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;聊聊网络变压器的浪涌等级标准是怎样划分的呢&#xff1f; 在和做防雷产品的客户的深度沟通网络变压器产品选型中发现&#xff1a;客户对网络变压器的浪涌等级划分也很希望有更深的了解&#xff0c;今天就这个问题和…

2025年Google I/O大会上,谷歌展示了一系列旨在提升开发效率与Web体验的全新功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

ONLYOFFICE文档API:编辑器的品牌定制化

在当今数字化办公时代&#xff0c;文档编辑器已成为各类企业、组织和开发者不可或缺的工具之一。ONLYOFFICE 文档提供的功能丰富且强大的文档编辑 API&#xff0c;让开发者能够根据自己的产品需求和品牌特点&#xff0c;定制编辑器界面&#xff0c;实现品牌化展示&#xff0c;为…

HTTP/HTTPS与SOCKS5三大代理IP协议,如何选择最佳协议?

在复杂多变的网络环境中&#xff0c;代理协议的选择直接影响数据安全、访问效率和业务稳定性。HTTP、HTTPS和SOCKS5作为三大主流代理协议&#xff0c;各自针对不同场景提供独特的解决方案。本文将从协议特性、性能对比到选型策略&#xff0c;为您揭示如何根据业务需求精准匹配最…

远程调用 | OpenFeign+LoadBalanced的使用

目录 RestTemplate 注入 OpenFeign 服务 LoadBalanced 服务 LoadBalanced 注解 RestTemplate 注入 创建 配置类&#xff0c;这里配置后 就不用再重新new一个了&#xff0c;而是直接调用即可 import org.springframework.cloud.client.loadbalancer.LoadBalanced; import …

NSSCTF [NISACTF 2022]ezheap

2058.[NISACTF 2022]ezheap(堆溢出) [NISACTF 2022]ezheap 1.准备 2.ida分析 main函数 int __cdecl main(int argc, const char **argv, const char **envp) {char *command; // [esp8h] [ebp-10h]char *s; // [espCh] [ebp-Ch]setbuf(stdin, 0);setbuf(stdout, 0);s (cha…

【HarmonyOS Next之旅】DevEco Studio使用指南(二十七) -> 开发云函数

目录 1 -> 开发流程 2 -> 创建并配置函数 2.1 -> 创建函数 2.2 -> 配置函数 3 -> 开发函数 4 -> 调试函数 4.1 -> 前提条件 4.2 -> 通过本地调用方式调试函数 4.3 -> 通过远程调用方式调试函数 5 -> 部署函数 1 -> 开发流程 云函数…

Rust 学习笔记:闭包

Rust 学习笔记&#xff1a;闭包 Rust 学习笔记&#xff1a;闭包用闭包捕获环境闭包类型推断和注释捕获引用或移动所有权将捕获的值移出闭包和 Fn Traits Rust 学习笔记&#xff1a;闭包 Rust 的闭包是匿名函数&#xff0c;可以保存在变量中&#xff0c;也可以作为参数传递给其…