项目:双人五子棋对战-对战模块(6)
完整代码见: 邹锦辉个人所有代码: 测试仓库 - Gitee.com
当玩家进入到游戏房间后, 就要开始一局紧张而又刺激的五子棋对战了, 本文将就前端后端的落子与判断胜负的部分作详细讲解.
模块详细讲解
约定前后端交互的接口
首先是建立连接后, 服务器需要生成一些游戏的初始信息(可以看作初始化游戏地图这样式儿的), 并将这些信息告诉给客户端(响应).
建立连接: ws://127.0.0.1:8080/game
{
message: 'gameReady', //消息的类型是 游戏就绪
ok: true,
reason: '',
roomId: '12345678', //玩家所处房间id
thisUserId: 1, //玩家自己的id
thatUserId: 2, //玩家对手的id
whiteUser: 1 //哪个玩家是执白子
}
这些内容都是玩家匹配成功之后, 服务器生成的内容, 需要把这个请求返回给浏览器.
在初始化内容之后, 双方玩家就需要轮流进行落子了, 同时落子这个逻辑, 既要展示, 也要交给服务器处理, 看一下放哪了, 有没有分清胜负啊什么的. 要传递的内容有: 落子玩家id, 落子位置(row, col).
同理, 响应就是返回一下你比赛结果: 谁输谁赢, 还是继续?
请求:
{
message: 'putChess',
userId: 1,
row: 0,
col: 0
}
响应:
{
message: 'putChess',
userId: 1,
row: 0,
col: 0,
winner: 0
}
如果winner为0, 还需要继续对战, 而如果winner非零, 就已经分出胜负了(winner的数字就表示胜利玩家的对战时玩家的id, 也就是1, 2)
前端代码
这里我们使用game_room.html(这个就是匹配成功之后要跳转的页面), 这里我们就希望显示出棋盘和提示信息(该谁落子了).
首先利用原先的方式创建WebSocket.
let websocketUrl = "ws://" + location.host + "/game";
let websocket = new WebSocket(websocketUrl);websocket.onopen = function () {console.log("连接游戏房间成功!");
}websocket.close = function () {console.log("和游戏服务器断开连接");
}websocket.onerror = function () {console.log("和服务器的连接出现异常!");
}//页面关闭前, 主动断开
window.onbeforeunload = function () {websocket.close();
}
然后进行初始化的逻辑:
websocket.onmessage = function (event) {console.log("[handlerGameReady] " + event.data);let resp = JSON.parse(event.data);if (!resp.ok) {alert("连接游戏失败! reason: " + resp.reason);// 如果出现连接失败的情况, 回到游戏大厅location.assign("/game_hall.html");return;}if (resp.message == 'gameReady') {gameInfo.roomId = resp.roomId;gameInfo.thisUserId = resp.thisUserId;gameInfo.thatUserId = resp.thatUserId;gameInfo.isWhite = (resp.whiteUser == resp.thisUserId);//初始化棋盘initGame();//设置显示区域的内容setScreenText(gameInfo.isWhite);} else if (resp.message == 'repeatConnection') {alert("检测到游戏多开! 请使用其他账号登录!");location.assign("/login.html");}
}
这里主要是对于棋盘的初始化内容(这个初始化的函数(initGame)中其实也包含后面对于落子的处理即websocket.onmessage. 所以这个函数实际上是客户端的主体部分).
对于initGame(), 它包含了一系列的对战处理逻辑:
1.对于棋盘的绘制, 棋子的绘制(这里使用了canvas, 不做详细介绍)
2.对于落子时对应位置的坐标计算, 文本框状态的转换
3.对于相应位置的落子情况, 向服务器发送请求.
4.对于接收到的响应, 如果分出胜负, 则对其进行处理
后端代码
要注意的是, 不仅在前端要有一个用来展示的棋盘, 同时, 在服务器内部, 也需要维护一个"棋盘". 服务器就根据每次的落子请求, 在棋盘上进行更新. 还需要对胜负进行判定.
这里也还是用到了WebSocket的通信特性:
这里需要注意, 客户端和服务器上的棋盘是有区别的:
1.客户端棋盘: 客户端只需要对于落子情况进行保存即可(这个位置有没有落子)
2.服务器棋盘: 服务器不仅需要得知是否落子, 还需得知是谁落的子, 这样才能进行输赢判断
而这里为什么要这么设置呢? 因为一般是服务器进行的输赢逻辑判定.
接下来, 当每次落子之后, 就会进行输赢的判定, 判定规则就是: 落子所在行/列/主对角线/副对角线是否其它连续的5个子与其相同, 就判定胜利.即:
这里仅列举一种即可, 代码很简单, 看看就可以:
//1.检查所有的行//先遍历五种情况for(int c = col - 4; c <= col; c++) {// 针对其中一种情况, 来判定这五个子是不是连在一起了try {if(board[row][c] == chess&&board[row][c + 1] == chess&&board[row][c + 2] == chess&&board[row][c + 3] == chess&&board[row][c + 4] == chess) {//构成了五子连珠, 胜负已分return chess == 1 ? user1.getUserId() : user2.getUserId();}} catch (ArrayIndexOutOfBoundsException e) {//如果出现数组下标月结的情况, 直接忽略这个异常.continue;}}
同时, 也可写一个方法用于打印棋盘, 这样可以观察执行情况.
五子棋双人对战项目到此也就结项了, 下一期将对该项目进行测试, 敬请期待!
相关文章:

项目:双人五子棋对战-对战模块(6)
完整代码见: 邹锦辉个人所有代码: 测试仓库 - Gitee.com 当玩家进入到游戏房间后, 就要开始一局紧张而又刺激的五子棋对战了, 本文将就前端后端的落子与判断胜负的部分作详细讲解. 模块详细讲解 约定前后端交互的接口 首先是建立连接后, 服务器需要生成一些游戏的初始信息(可…...

LeakSearch:针对网络公开凭证的安全扫描与检测工具
关于LeakSearch 在红队演戏过程中,往往需要获取到针对目标域的访问权限。在这个过程中,很多红队人员会选择使用暴露在互联网上的代理服务器来实现目标域的访问,那么此时就需要在互联网上收集公开暴露的凭证信息。 对于蓝队来说,…...

ArcoDesgin a-model中自定义样式model-class无效
增加黄框代码解决 原因是,动态加载的组件默认渲染在body下面,与#app平级。样式设置无效 加上:render-to-body“false”,让组件不渲染到body下,渲染在app下面,样式设置生效...
持续总结中!2024年面试必问 20 道分布式、微服务面试题(十)
上一篇地址:持续总结中!2024年面试必问 20 道分布式、微服务面试题(九)-CSDN博客 十九、请描述一种微服务部署策略。 微服务部署策略是确保微服务架构中各个独立服务能够高效、稳定地部署到生产环境中的方法。以下是一些常见的微…...

北航第四次数据结构与程序设计编程题复习
到期末了,所以再来复习一下以前的作业。 北航第四次数据结构与程序设计编程题 一、栈操作(栈-基本题)二、C程序括号匹配检查三、计算器(表达式计算-后缀表达式实现,结果为浮点)四、文本编辑操作模拟&#…...
golang调用外部程序包os/exec中的 Command和CommandContext 函数创建的Cmd对象的区别
在go语言中,我们可以通过os/exec包中的Command和CommandContext 函数创建对应的外部程序执行Cmd对象, 这2个函数创建的cmd命令执行对象是有区别的,CommandContext创建的对象可以携带上下文,这个主要用于我们通过cancel函数给对应的…...

Redis进阶知识个人汇总
持久化 三种方式实现它的持久化: RDB持久化 全称Redis数据备份文件,又称Redis数据快照 这种就是将Redis内存中所有数据记录到磁盘中,当实例出故障后,从磁盘中读快照文件进行恢复数据。 一般使用bgsave指令实现 复制主线程得到一…...
从中序与后序遍历序列构造二叉树-力扣
中序遍历序列存放节点的顺序是左中右,后序遍历存放节点的顺序是左右中后序遍历序列的最后一个节点即为二叉树的根节点由于每个值在二叉树中都是唯一的,那么根据根节点的值,就可以将中序遍历序列一分为二,前部分存储的是根节点左子…...

操作系统期末复习(大题)
1. 进程调度 周转时间作业完成时刻-作业到达时刻 带权周转时间周转时间/服务时间 平均周转时间各个作业周转时间之和/作业个数 操作系统:周转时间和其他时间_系统为作业提供的时间-CSDN博客 2. 进程调度 3. 调度算法 4. 临界区互斥访问问题 即证明是否满足互斥&a…...

解决富文本中抖音视频无法播放的问题——403
问题 富文本中的抖音视频无法播放,资源状态码是403禁止访问打开控制台,可以看到在项目中打开,数据请求的请求头多了一个Referer: http://localhost:3000/而复制链接在新窗口直接打开,请求头中并不会携带Referer 解决方案 在ind…...
2024最新华为OD机试(C卷+D卷)真题目录+使用说明+在线评测
文章目录 📒声明🎚专栏介绍📖试读文章🎀关于华为OD 🧷真题目录2024最新 C卷 & D卷 目录(实时跟新中~)2024最新 C卷 & D卷 100分题目 (实时跟新中~)2024最新 C卷 & D卷 200分题目 (实时跟新中~) Ǵ…...
hana 中的缓存视图功能,类似ORACLE 中的 物化视图功能
为什么启用物化视图、缓存视图这里就不过多解释了。 参考官方文章: Static Result Cache | SAP Help Portal 在 HANA中,视图的缓存分 静态结果缓存 和 动态结果缓存。 静态结果缓存和动态结果缓存是缓存查询结果以获得性能优势的可配置应用程序。 缓…...

express入门02静态资源托管
目录 1 搭建静态资源结构2 代码助手3 多目录托管4 服务器热启动总结 上一篇我们讲解了使用express搭建服务器的过程,服务器搭建好了之后,除了在地址栏里输入URL发起get请求或者post请求外,通常我们还需要访问静态资源,比如html、c…...

Java常见的引用类型
1、强引用:普通的变量引用,Student sutnew Student(); 2、软引用:堆内对象若未被引用,GC不会立刻删除,而是在堆内存空间不足时才会进行删除。 3、弱引用:GC触发,会立刻删除。 4、虚引用&am…...

使用易备数据备份软件,简单快速地备份 Oracle 数据库
易备数据备份软件能够以简单高效的方式,实现对 Oracle 数据库的保护。 易备数据备份软件数据库备份功能的关键特性 自动保护网站数据库及应用程序实时备份,不需要任何中断或数据库锁定基于日期和时间的备份任务计划可恢复到一个已存在的数据库或创建一…...

基于SSM+Jsp的交通事故档案管理系统
开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…...

深度解析:ChatGPT全面测评——功能、性能与用户体验全景剖析
从去年底至今,由 OpenAI 发布的大规模语言模型 ChatGPT 引发了几乎所有科技领域从业者的高度关注。据瑞银集团的报告显示,自 2023 年 1 月起,仅两个月内,ChatGPT 的月活用户数便超过了 1 亿。 ChatGPT 被誉为“最强 AI”ÿ…...

领夹麦克风哪个品牌好?哪个麦克风好?揭秘无线麦克风十大排名!
无线领夹麦克风因其便携性和高音质而备受青睐。今天,我要为大家推荐几款备受赞誉的无线领夹麦克风,它们不仅在音质上表现出色,更在设计和性能上各有千秋。这些麦克风不仅适合专业录音师使用,也适合普通用户在日常生活中的各种场…...
低代码开发:智能财务系统开发应用
在当今数字化时代,企业对于高效的财务管理系统需求日益增长。低代码开发平台为开发智能财务系统提供了快速、灵活的解决方案,使企业能够快速构建、定制和部署应用程序,提升财务管理效率。本文将探讨低代码开发在智能财务系统开发应用中的应用…...

Windows 10 找不到Microsoft Edge 浏览器
下载链接 了解 Microsoft Edge 手动下载浏览器 问题说明 一般来说,windows10系统应该是自带浏览器edge的,但有的电脑就是没有找到edge浏览器,可能系统是精简过的,可能是被卸载了。如下,控制面板确实没找到程序。 …...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...