项目:双人五子棋对战-对战模块(6)

news2024/11/17 11:53:17

完整代码见: 邹锦辉个人所有代码: 测试仓库 - 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;
            }
        }

 同时, 也可写一个方法用于打印棋盘, 这样可以观察执行情况.

 五子棋双人对战项目到此也就结项了, 下一期将对该项目进行测试, 敬请期待!

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

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

相关文章

一五零、MAC 安装mysql可视化工具连接

mysql安装&#xff0c;按照网上教程一步步安装&#xff08;官网下载安装包->解压->完成安装&#xff09;&#xff0c;最后在「系统偏好设置」无法启动mysql。 原因&#xff1a;下载的版本是8.0最新版本&#xff0c;MAC上这种方法无法启动成功。 解决方法 换低版本的mys…

JDBC开发之四大核心API:DriverManager Connection Statement ResultSet

DriverManager 方法都是静态的 注册驱动 在Mysql5之后我们就不用注册驱动了 在jar包里已经写好了 读取文件 第二个方法 如果连接的是主机mysql并且端口是默认的3306 则可以简化书写 代码书写 import java.sql.Connection; import java.sql.DriverManager; import java.sql.S…

微软的这个按钮又双叒叕变了位置?有时候还不见了……

前言 小白最近打开Windows11系统的时间比较少&#xff0c;大部分时间都还是喜欢用MacBookPro码字。 之前小白写过一篇关于微软系统左下角的这个神奇按钮 Windows11更新之后&#xff0c;电脑左下角多出了一个奇怪的按钮&#xff08;点我跳转查看&#xff09; 没错&#xff0…

vivado HW_SIO_GT

描述 Xilinx的可定制LogiCORE™IP集成误码率测试仪&#xff08;IBERT&#xff09;核心 FPGA是为评估和监控千兆收发器&#xff08;GTs&#xff09;而设计的。IBERT core支持系统内串行I/O验证和调试&#xff0c;使您能够进行测量和优化 您的设计中的高速串行I/O链路。参考综合误…

webpack--压缩,代码的拆分,tree shinking

Terser 对代码进行压缩、丑化 const TerserPlugin require("terser-webpack-plugin");optimization: { minimize: true, //在开发环境下启用 CSS 优化minimizer: [new TerserPlugin({extractComments: false,terserOptions: {compress: {arguments: true,// 将函数…

CAPL如何发送一条SYN报文

在TCP协议中,发起连接的Client端首先会发送一条SYN报文,用来发起TCP连接请求。这条SYN报文的本质是TCP报文,只不过flags字段中SYN位置为1。 且SYN的序列号是随机的,所以可以用一个随机函数来生成随机数。而ack确认号是0。 TCP报文和UDP报文一样,需要设置源和目标端口号,…

最新小红薯引流无限曝光机,轻松高效精准曝光引流【引流软件+使用教程】

在现代数字营销的海洋中&#xff0c;精准引流已成为商家及创业者追求的圣杯。一种无需采集ID的新策略突破了传统营销的局限&#xff0c;提供了一条高效且安全的道路。这种方法旨在通过有针对性的关键词触达潜在的兴趣群体&#xff0c;实现品牌与用户之间的高效对接。 以关键词…

【CW32F030CxTx StartKit开发板】构建开发环境,测试LED和UART例程

目录 1、开发环境的构建 2、硬件连线 3. 例程测试 3.1 LED示例 3.2 UART printf示例 本文首发于21ic&#xff1a;https://bbs.21ic.com/forum.php?modviewthread&tid3382698&page1#pid14103102 感谢21ic和武汉芯源提供的测试机会。 此次测试的是CW32F030CxTx S…

新手grub 配置介绍

最近因为工作需要接触了grub&#xff0c;学到了一些相关知识&#xff0c;所以在这里写篇博客记录一下&#xff0c;有不对的部分欢迎指正。 目录 grub是什么&#xff1f; grub有哪些配置文件&#xff1f; 各配置文件区别 配置文件生成流程 配置文件有哪些内容&#xff1f;…

【Nature子刊】最争气国人友好“灌水刊”,中科院3区升2区,录用仅1个月,2天见刊!

本周投稿推荐 SSCI • 中科院2区&#xff0c;6.0-7.0&#xff08;录用友好&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&#xff09; SCI&EI • 4区生物医学类&#xff0c;0.5-1.0&#xff08;录用…

Android Studio | 小白如何运行别人的安卓项目

目录 Step1&#xff1a;正确地打开项目 Step2&#xff1a;AS 同步时报错 Step3&#xff1a;同步完成后启动 Step4&#xff1a;启动成功 说明&#xff1a;本文简称 Android Studio 为 AS Step1&#xff1a;正确地打开项目 重点&#xff1a;确认好项目的根目录是哪个目录&am…

TCL电视销量蝉联全球第二,打出美洲杯欧洲杯营销王牌

四年一度的欧洲杯即将于6月14日至7月14日在德国举办。作为全球顶级的足球赛事&#xff0c;欧洲杯不仅受到全世界球迷的瞩目&#xff0c;同样赢得了中国品牌的青睐。 近日&#xff0c;TCL宣布成为德国、西班牙、意大利、波兰、斯洛伐克5支国家队的官方合作伙伴&#xff0c;携手…

idea插件开发之定义侧边栏

写在前面 看下如何在侧边栏定义窗口&#xff0c;如下的效果&#xff1a; 1&#xff1a;正戏 先来定义UI&#xff0c;随便拖拽个组件&#xff0c;就看个效果&#xff1a; 接着定义一个工厂类来创建这个UI&#xff0c;需要实现接口com.intellij.openapi.wm.ToolWindowFactor…

零基础非科班也能掌握的C语言知识20 文件操作

文件操作 1.文件相关概念2.流和标准流2.1流2.2标准流 3.文件指针4.文件的打开关闭5.文件的顺序读写6.文件的随机读写6.1 fseek6.2 ftell6.3 rewind 7.⽂件读取结束的判定7.1 feof 8.文件缓冲区 1.文件相关概念 2.流和标准流 2.1流 我们程序的数据需要输出到各种外部设备&…

4 最简单的 C 程序设计—顺序程序设计-4.1 C语句概述-C程序的结构

C 语句可分为以下五类&#xff1a; 1) 表达式语句 2) 函数调用语句 3) 控制语句 4) 复合语句 5) 空语句 当然&#xff0c;C语言中的确可以按照您列举的这五种类别来划分语句。下面我将分别给出每个类别的一些典型代码案例&#xff1a; 1. 表达式语句 表达式语句是最基本的语…

【CTF-Events】R3CTF/YUANHENGCTF 2024 两道密码题记录一下

R3CTF2024 WP 文章目录 R3CTF2024 WPCryptoR0System考点&#xff1a;代码审计 ECDH R1System考点&#xff1a;代码审计 ECDH Crypto R0System 考点&#xff1a;代码审计 ECDH 打开代码后有两个小系统&#xff0c;看一下功能 然后再看一下登录之后有哪些功能 其实到这里就可以…

服务器端口,服务器远程端口修改操作

在进行服务器端口和远程端口的修改操作时&#xff0c;必须确保具备相应的网络知识和实践经验&#xff0c;以避免因操作不当而导致的数据丢失或网络故障。下面将详细阐述这一操作的流程和注意事项。 一、端口修改操作前准备 1. 深入了解当前网络环境和配置&#xff0c;包括服务…

在微信小程序中安装和使用vant框架

目录 1、初始化项目2、安装vant相关依赖3、修改 app.json4、修改 project.config.json5、构建npm6、使用示例 本文将详细介绍如何在微信小程序中安装并使用vant框架&#xff5e; 开发工具&#xff1a;微信开发者工具 1、初始化项目 从终端进入小程序项目目录&#xff0c;执行…

24年中级会计考试报名明天开始啦,速速查收报名流程!

&#x1f62d;&#x1f62d;姐妹们&#xff01;24年中级会计明天就要开始报名了&#xff01;距离24年中级会计考试还有90天时间&#xff0c;还没开始备考的姐妹们真的要紧张起来了&#xff01;今天给大家整理了一份24中级会计详细报名流程&各地报名时间&#xff0c;附备考工…

16. 《C语言》——【牛客网BC124 —— BC130题目讲解】

亲爱的读者&#xff0c;大家好&#xff01;我是一名正在学习编程的高校生。在这个博客里&#xff0c;我将和大家一起探讨编程技巧、分享实用工具&#xff0c;并交流学习心得。希望通过我的博客&#xff0c;你能学到有用的知识&#xff0c;提高自己的技能&#xff0c;成为一名优…