项目:双人五子棋对战-对战模块(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;
            }
        }

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java程序在运行过程各个内部结构的作用

一&#xff1a;内部结构 一个进程对应一个jvm实例&#xff0c;一个运行时数据区&#xff0c;又包含多个线程&#xff0c;这些线程共享了方法区和堆&#xff0c;每个线程包含了程序计数器、本地方法栈和虚拟机栈接下来我们通过一个示意图介绍一下这个空间。 如图所示,当一个hell…

63-目录操作(QDir类)及展示系统文件实战

一、目录操作(QDir 类) #include <QCoreApplication>#include <QDir> #include <QStringList> #include <QtDebug>// 自定义函数实现获取目录下大小qint64 GetDirFileInfoSizeFunc(const QString &qpath) {// QDir类专门用来操作路径名称或底层文…

catia零件装配时预览零件的形状

这样的显示方式看不到 选择大或中图标就可预览零件形状

Qt | openSSL将TCP数据进行不对称(RSA)加密传输-windows平台实操(可行)

01、windows平台工具准备 QtQt5.14.2openSSL下载(选择适合自己的版本即可)https://slproweb.com/products/Win32OpenSSL.htmlTCP调试助手调试助手02、简介 首先简单介绍一下openssl。接着描述如何在windo

新增多种图表类型,新增视频、流媒体、跑马灯组件,DataEase开源数据可视化分析工具v2.7.0发布

2024年6月11日&#xff0c;人人可用的开源数据可视化分析工具DataEase正式发布v2.7.0版本。 这一版本的功能变动包括&#xff1a;图表方面&#xff0c;新增对称条形图、桑基图、流向地图、进度条等图表类型&#xff0c;并对已有的仪表盘、指标卡、明细表、汇总表、水波图、象限…

(十二)人工智能应用--深度学习原理与实战--模型编译及训练参数的选择

神经网络模型的编译实际上是为网络指定几个非常重要的运行参数,包括优化器、损失函数(误差函数】和评价指标,这三者也代表着神经网络的核心运行机制----通过损失函数来计算网络误差、通过优化器来调整网络参数以降低误差、通过评价指标来衡量网络的性能。神经网络训练时除了…

香港裸机云多IP服务器与普通独享IP服务器的区别

在当前的云计算和服务器托管领域&#xff0c;香港裸机云多IP服务器和普通独享IP服务器是两种常见的选择。它们各自具有独特的特点和优势&#xff0c;适用于不同的应用场景。以下是对这两种服务器类型的详细比较&#xff1a; 一、概念定义 香港裸机云多IP服务器&#xff1a;这是…

【因果推断python】28_面板数据和固定效应2

目录 固定效应 固定效应 为了方面后面更正式地讲述&#xff0c;让我们首先看一下我们拥有的数据。按照我们的例子&#xff0c;我们将尝试估计婚姻对收入的影响。我们的数据包含多年以来多个个体 (nr) 的这两个变量&#xff0c;married 和lwage。请注意&#xff0c;工资采用对数…

【iOS】—— 响应者链和事件传递链

【iOS】—— 响应者链和事件传递链 响应者连和事件传递链概念响应者响应链事件响应者响应链事件iOS中的事件类型&#xff1a;UIKit继承图UIRseponderUITouchUIEvent 事件的产生与传递传递链传递过程 总结 响应者连和事件传递链 概念 响应者 由离用户最近的view向系统传递。i…

【CGAL】Region_Growing检测圆柱,保存结果并输出圆柱体参数

目录 说明代码展示结果展示问题说明 说明 这篇博客以代码为主&#xff0c;使用CGAL中的region growing方法检测圆柱体。将不同的圆柱按不同颜色保存&#xff0c;并输出圆柱体的中心坐标、轴方向以及半径。 region growing的具体思想网上的文章已经有很多&#xff0c;可以参考这…

安装mysql5.7,然后安装mysql workbench进行管理。

1、下载mysql5.7 MySQL :: Download MySQL Installer 这个是32位的安装版 MySQL :: Download MySQL Community Server (Archived Versions) 这个是zip版 这里我下载的是zip版本。 下载完成后&#xff0c;解压缩&#xff0c;然后新建文件my.ini进行配制。 my.ini [mysqld]…

Django DetailView视图

Django的DetailView是一个用于显示单个对象详情的视图。下面是一个使用DetailView来显示单个书籍详情的例子。 1&#xff0c;添加视图 Test/app3/views.py from django.shortcuts import render# Create your views here. from django.views.generic import ListView from .m…

数据结构预备知识(Java):包装类泛型

1、包装类 1.1 包装类 在Java中&#xff0c;每一个基本数据类型都有一个对应的包装类&#xff1a; 在SE的学习中我们已有过简单了解。 我们可以注意到&#xff0c;除了int类型的包装类为Integer&#xff0c;char类型的包装类为Character外&#xff0c;其余基本类型的包装类均…

wordpress主题开发

科普一&#xff1a;wordpress 是一套用 php 这个语言写的CMS后台管理系统&#xff0c;即我们大家的 wordpress 网站后台是一样的&#xff0c;能体现我们网站外观不同的地方就在于wordpress主题&#xff08;即皮肤&#xff09;&#xff0c;而这个主题的基本构成是 htmlcssjavasc…

JMH309【亲测】典藏3D魔幻端游【剑踪3DⅢ】GM工具+开区合区工具+PC客户端+配置修改教程+Win一键服务端+详细外网视频教程

资源介绍&#xff1a; 经典不错的一款端游 GM工具开区合区工具PC客户端配置修改教程Win一键服务端详细外网视频教程 资源截图&#xff1a; 下载地址

任务倒计时App

设计背景 在某一阶段可能需要给自己设置长期任务&#xff0c;比如找工作、考研等&#xff0c;需要一个单纯的任务计时工具&#xff0c;设置完任务的目标时间后&#xff0c;每次打开App时都能直接看到最新的剩余时间 设计步骤 1. 写java源码 由于需要界面显示&#xff0c;需…

使用MySQL

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 1 下载安装MySQL MySQL是一款开源的数据库软件&#xff0c;由于其免费特性得到了全世界用户的喜爱&#xff0c;是目前使用人数最多的数据库。下面将…

Unity【入门】重要组件和API

Unity重要组件和API 文章目录 1、最小单位GameObject1、成员变量2、静态方法1、代码创建Unity自带几何体 CreatePrimitive2、查找对象3、实例化对象&#xff08;克隆对象&#xff09;的方法4、删除对象的方法5、切换场景不移除 3、成员方法1、创建空物体2、为对象动态添加脚本(…

基数排序详解

目录 一、桶排序思想 1.1 什么是桶排序 1.2 桶排序的步骤 二、基数排序思想 2.1 什么是基数排序 2.2 实现方式 2.3 图解 三、代码思路 3.1 前置工作 3.2 映射 3.3 排序 四、C语言源码 一、桶排序思想 1.1 什么是桶排序 桶排序(Bucket sort)是一种排序算法&#xff…

网络安全课程开发

我们为卡巴斯基实验室开发了一个交钥匙教育门户网站&#xff0c;并为其开设了网络安全课程。在资源上&#xff0c;你可以熟悉课程的理论部分-观看视频或阅读插图文本版本&#xff0c;然后通过回答问题来验证你的知识。通过最终测试后&#xff0c;用户将获得证书。 对于这个项目…