项目实战--网页五子棋(对战功能)(8)

上期我们完成了websocket建立连接后的数据初始化,今天我们完成落子交互的具体代码:
这里我们先复习一下,之前约定好的落子请求与响应包含的字段:

 1. 发送落子请求

 我们在script.js文件中找到落子的相关方法,增加发送请求的代码:
 

    chess.onclick = function (e) {if (over) {return;}if (!me) {return;}let x = e.offsetX;let y = e.offsetY;// 注意, 横坐标是列, 纵坐标是行let col = Math.floor(x / 30);let row = Math.floor(y / 30);if (chessBoard[row][col] == 0) {// TODO 发送坐标给服务器, 服务器要返回结果webSocket.send(JSON.stringify({message: 'putChess',userId: gameInfo.userId1,row: row,col: col}));oneStep(col, row, gameInfo.isBlack);chessBoard[row][col] = 1;}}

2. 处理请求发送响应

    @Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {//1. 获取用户信息User user = (User)session.getAttributes().get("user");//2. 获取请求信息GameRequest request = objectMapper.readValue(message.getPayload(),GameRequest.class);//3. 调用游戏房间中的putChess方法实现落子Room room = roomManager.getRoomByUserId(user.getUserId());room.putChess(request);}

实现putChess:

    private static int ROW = 15;private static int COL = 15;//棋盘, 0表示未落子,1表示玩家1的子,2表示玩家2的子private int[][] board = new int[ROW][COL];//处理落子请求public void putChess(GameRequest request) throws IOException {//1. 判断落子玩家int chess = request.getUserId() == user1.getUserId() ? 1 : 2;int row = request.getRow();int col = request.getCol();//2. 落子if(board[row][col] != 0) {System.out.println("[" + row + "," + col + "]已经有子了");return;}board[row][col] = chess;//3. 判断是否获胜int winnerId = checkWinner(row, col) ? request.getUserId() : -1;//4. 给房间中的玩家返回响应GameResponse response = new GameResponse();response.setMessage("putChess");response.setUserId(request.getUserId());response.setRow(row);response.setCol(col);response.setWinnerId(winnerId);//通过OnlineUserManager获取房间中的玩家WebSocketSession session1 = onlineUserManager.getFromRoom(user1.getUserId());WebSocketSession session2 = onlineUserManager.getFromRoom(user2.getUserId());//判断是否有玩家下线if(session1 == null) {//玩家1下线,玩家2获胜response.setWinnerId(user2.getUserId());System.out.println("玩家1掉线");}if(session1 == null) {//玩家2下线,玩家1获胜response.setWinnerId(user1.getUserId());System.out.println("玩家2掉线");}String resp = objectMapper.writeValueAsString(response);if(session1 != null) {session1.sendMessage(new TextMessage(resp));}if(session2 != null) {session2.sendMessage(new TextMessage(resp));}if(response.getWinnerId() != -1) {System.out.println("分出胜负, 游戏房间:" + roomId + "即将销毁");roomManager.remove(roomId, user1.getUserId(), user2.getUserId());}}

注意:我们并没有把Room注册为Spring组件,进行依赖注入时,需要在构造方法中手动注入:

    public Room() {roomId = UUID.randomUUID().toString();onlineUserManager = J20250110GoBangApplication.context.getBean(OnlineUserManager.class);objectMapper = J20250110GoBangApplication.context.getBean(ObjectMapper.class);roomManager = J20250110GoBangApplication.context.getBean(RoomManager.class);}

 实现checkWinner方法检测是否获胜:
 

    private boolean checkWinner(int row, int col) {int count = 1;//判断行是否五子连珠for(int i = col + 1; i < COL; i++) {if(board[row][i] == board[row][col]) {count++;}else{break;}}for(int i = col - 1; i >= 0; i--) {if(board[row][i] == board[row][col]) {count++;}else{break;}}if(count >= 5) {return true;}//判断列是否五子连珠count = 1;for(int i = row + 1; i < ROW; i++) {if(board[i][col] == board[row][col]) {count++;}else{break;}}for(int i = row - 1; i >= 0; i--) {if(board[i][col] == board[row][col]) {count++;}else{break;}}if(count >= 5) {return true;}//判断左上到右下斜线是否五子连珠count = 1;for(int i = row + 1, j = col + 1; i < ROW && j < COL; i++, j++) {if(board[i][j] == board[row][col]) {count++;}else{break;}}for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {if(board[i][j] == board[row][col]) {count++;}else{break;}}if(count >= 5) {return true;}//判断右上到左下斜线是否五子连珠count = 1;for(int i = row - 1, j = col + 1; i >= 0 && j < COL; i--, j++) {if(board[i][j] == board[row][col]) {count++;}else{break;}}for(int i = row + 1, j = col - 1; i < ROW && j >= 0; i++, j--) {if(board[i][j] == board[row][col]) {count++;}else{break;}}if(count >= 5) {return true;}return false;}

3. 处理落子响应

在之前初始化游戏的代码中,我们在游戏初始化完成时会调用initGame()方法:

于是我们可以在initGame方法末尾中修改onmessages使之变为处理落子响应的方法:

    webSocket.onmessage = function (e) {let resp = JSON.parse(e.data);console.log(resp);if (resp.message != 'putChess') {console.log("响应类型错误");return;}//判断是谁落子if (resp.userId == gameInfo.userId1) {//根据对应棋子颜色绘制棋子oneStep(resp.col, resp.row, gameInfo.isBlack);} else if (resp.userId == gameInfo.userId2) {//根据对应棋子颜色绘制棋子oneStep(resp.col, resp.row, !gameInfo.isBlack);} else {console.log("响应出错 userId:" + resp.userId);return;}// 给对应的位置设置为1,表示有子chessBoard[resp.row][resp.col] = 1;//交互落子方me = !me;setScreenText(me);//判断游戏是否结束if (resp.winnerId == gameInfo.userId1) {over = true;alert("你赢了!!!");location.href = "/hall.html";}if (resp.winnerId == gameInfo.userId2) {over = true;alert("你输了");location.href = "/hall.html";}}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0开始的操作系统手搓教程24——完成我们的键盘驱动子系统

目录 所以&#xff0c;我们现来说说转义字符 我们需要如何处理扫描码 当键入的是双字符键时 当键入的是字母键时 下一篇 我们下面来看看我们的键盘驱动子系统是一个怎么个事情。 驱动程序&#xff0c;你可以认为是对硬件的一层封装。我们按照手册规格的规定姿势&#xff0…

根据输入汉字生成带拼音的米字格字帖

实现了下面功能&#xff1a; 1、根据输入汉字&#xff0c;自动调整米字格和四线格的行数&#xff1b; 2、给汉字自动加上拼音和声调&#xff08;暂时不考虑多音字&#xff09;&#xff1b; 3、汉字在米字格&#xff0c;拼音在四线格&#xff0c; 4、第一列用黑色&#xff0c;2-…

软件高级架构师 - 软件工程

补充中 测试 测试类型 静态测试 动态测试 测试阶段 单元测试中&#xff0c;包含性能测试&#xff0c;如下&#xff1a; 集成测试中&#xff0c;包含以下&#xff1a; 维护 遗留系统处置 高水平低价值&#xff1a;采取集成 对于这类系统&#xff0c;采取 集成 的方式&…

DeepSeek专题:DeepSeek-V2核心知识点速览

AIGCmagic社区知识星球是国内首个以AIGC全栈技术与商业变现为主线的学习交流平台&#xff0c;涉及AI绘画、AI视频、大模型、AI多模态、数字人以及全行业AIGC赋能等100应用方向。星球内部包含海量学习资源、专业问答、前沿资讯、内推招聘、AI课程、AIGC模型、AIGC数据集和源码等…

电脑如何拦截端口号,实现阻断访问?

如果你弟弟喜欢玩游戏&#xff0c;你可以查询该应用占用的端口&#xff0c;结合以下方法即可阻断端口号&#xff0c;让弟弟好好学习&#xff0c;天天向上&#xff01; 拦截端口可以通过防火墙和路由器进行拦截 &#xff0c;以下是常用方法&#xff1a; 方法 1&#xff1a;使用…

【NLP 32、文本匹配任务 —— 深度学习】

大劫大难以后&#xff0c;人不该失去锐气&#xff0c;不该失去热度&#xff0c;你镇定了却依旧燃烧&#xff0c;你平静了却依旧浩荡&#xff0c;致那个从绝望中走出来的自己&#xff0c;共勉 —— 25.1.31 使用深度学习在文本匹配任务上主要有两种方式&#xff1a;① 表示型 ②…

【AD】5-15 Active Route的自动布线辅助

1.如图所示点击Panels&#xff0c;打开Active Route 2.按如图设置后&#xff0c;点击向导走线确定好走向后&#xff0c;在点击自动辅助布线&#xff0c;布好后可自行微调

使用 Arduino 和 ThingSpeak 通过 Internet 进行心跳监测

使用 Arduino 和 ThingSpeak 通过 Internet 进行心跳监测 在这个项目中,我们将使用 Arduino 制作一个心跳检测和监测系统,该系统将使用脉搏传感器检测心跳,并在与其连接的 LCD 上显示 BPM(每分钟心跳次数)读数。它还将使用 Wi-Fi 模块ESP8266将读数发送到 ThingSpeak 服务…

正则表达式,idea,插件anyrule

​​​​package lx;import java.util.regex.Pattern;public class lxx {public static void main(String[] args) {//正则表达式//写一个电话号码的正则表达式String regex "1[3-9]\\d{9}";//第一个数字是1&#xff0c;第二个数字是3-9&#xff0c;后面跟着9个数字…

分析不同高度障碍物检测情况

import re import matplotlib.pyplot as plt from datetime import datetime import matplotlib.dates as mdates from matplotlib.font_manager import FontProperties# 设置中文字体 font_path /usr/local/sunlogin/res/font/wqy-zenhei.ttc # 替换为你的实际字体路径 my_f…

Qt添加MySql数据库驱动

文章目录 一. 安装MySql二.编译mysql动态链接库 Qt版本&#xff1a;5.14.2 MySql版本&#xff1a;8.0.41 一. 安装MySql 参考这里进行安装&#xff1a;https://blog.csdn.net/qq_30150579/article/details/146042922 将mysql安装目录里的bin&#xff0c;include和lib拷贝出来…

算法005——有效三角形个数

力扣——有效三角形个数点击链接跳转 判断三条边是否能组成三角形&#xff0c;大家第一时间想到的就是两边之和大于第三边 但是运用这个方法&#xff0c;我们需要判断三次&#xff0c;有一个更简单的方法&#xff0c;只需要判断一次 因为 C 已经是三边之中最大的了&#xff…

【大学生体质】智能 AI 旅游推荐平台(Vue+SpringBoot3)-完整部署教程

智能 AI 旅游推荐平台开源文档 项目前端地址 ☀️项目介绍 智能 AI 旅游推荐平台&#xff08;Intelligent AI Travel Recommendation Platform&#xff09;是一个利用 AI 模型和数据分析为用户提供个性化旅游路线推荐、景点评分、旅游攻略分享等功能的综合性系统。该系统融合…

Hive八股

Hive八股 一级目录二级目录三级目录 Hive1Hive1hive简介2hive架构3hive与Hadoop的关系4hive与传统数据库对比5hive的数据存储 2Hive表类型1 Hive 数据类型2 Hive 内部表&#xff01;&#xff01;&#xff01;3 Hive 外部表 external table&#xff01;&#xff01;&#xff01;…

Aruco 库详解:计算机视觉中的高效标记检测工具

1. 引言&#xff1a;Aruco 在计算机视觉中的重要性 在计算机视觉领域&#xff0c;标记&#xff08;Marker&#xff09;检测和识别是许多应用的基础&#xff0c;包括 机器人导航、增强现实&#xff08;AR&#xff09;、相机标定&#xff08;Calibration&#xff09;以及物体跟踪…

智慧消防新篇章:4G液位/压力传感器,筑牢安全防线!

火灾无情&#xff0c;防患未“燃”&#xff01;在智慧消防时代&#xff0c;如何实现消防水系统的实时监测、预警&#xff0c;保障人民生命财产安全&#xff1f;山东一二三物联网深耕物联网领域&#xff0c;自主研发4G液位、4G压力智能传感器&#xff0c;为智慧消防水位、水压无…

STM32 子设备通过CAN发送数据到主设备

采集ADC、GPS经纬坐标、温湿度数据、大气压数据通过CAN方式发送给主设备端&#xff0c;帧ID按照如下定义&#xff1a; 我尼玛一个标准帧ID位数据是11位&#xff0c;扩展帧才是111829位&#xff0c;它说最开头的是四位是真类型&#xff0c;并给我如下解释&#xff1a; 它把帧的定…

通过Golang的container/list实现LRU缓存算法

文章目录 力扣&#xff1a;146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2. 插入元素3. 删除元素4. 遍历链表5. 获取链表长度使用场景注意事项 源代码阅读 在 Go 语言中&#xff0c;container/list 包提供了一个双向链表的实现。链表是一种常见的数据结构&#…

模型微调-基于LLaMA-Factory进行微调的一个简单案例

模型微调-基于LLaMA-Factory进行微调的一个简单案例 1. 租用云计算资源2. 拉取 LLaMa-Factory3. 安装依赖环境4. 启动 LLaMa-Factory 界面5. 从 Huggingface 下载模型6. 模型验证7. 模型微调 1. 租用云计算资源 以下示例基于 AutoDL 云计算资源。 在云计算平台选择可用的云计…

ArcGIS操作:13 生成最小外接矩阵

应用情景&#xff1a;筛选出屋面是否能放下12*60m的长方形&#xff0c;作为起降场候选点&#xff08;一个不规则的形状内&#xff0c;判断是否能放下指定长宽的长方形&#xff09; 1、面积初步筛选 Area ≥ 720 ㎡ 面积计算见 2、打开 ArcToolbox → Data Management Tools …