C++项目:在线五子棋对战(网页版)
项目介绍
本项⽬主要实现⼀个⽹⻚版的五⼦棋对战游戏,其主要⽀持以下核⼼功能:
• 用户管理:实现用户注册,用户登录、获取用户信息、用户天梯分数记录、用户比赛场次记录等。
• 匹配对战:实现两个玩家在网页端根据天梯分数匹配游戏对⼿,并进行五子棋游戏对战的功能。
• 聊天功能:实现两个玩家在下棋的同时可以进⾏实时聊天的功能。
程序截图
开发环境
• Linux (Centos-7.6)
• VSCode/Vim
• g++/gdb
• Makefile
核心技术
• HTTP/WebSocket
• Websocket++
• JsonCpp
• Mysql
• C++11
• BlockQueue
• HTML/CSS/JS/AJAX
项目大流程
• 环境搭建(在Linux环境下安装需要用到的的工具以及第三方库)
• 框架设计
• 前置知识的了解
• 模块开发
配置开发环境
项目框架
项目期望:用户访问服务器获取注册页面,通过注册页面注册账号,注册成功后在登录页面进行登录。登录成功后进入游戏大厅,在游戏大厅中进行匹配对战,匹配成功,将进入游戏房间内与对手进行实时对战和实时聊天。
用户访问服务器获取的注册页面、登录页面、游戏大厅页面和游戏房间页面,属于静态资源请求。进行注册请求、登录请求、进入游戏大厅后展示个人信息的个人信息请求、匹配对战请求和下棋聊天请求属于动态功能请求。
服务器流程图:
模块解析
在项目中,需要用到6个模块,分别是:
数据管理模块:基于mysql数据库进行数据管理以及封装数据管理模块实现数据库访问。
在数据管理模块中,需要实现的功能有:注册新用户功能、登录验证功能、通过用户名获取用户信息功能、通过用户id获取用户信息功能,以及对战胜利和失败后,对数据的更新功能。
网络服务器模块:基于websocketpp库搭建websocket服务器,实现与客户端网络通信。
早网络服务器模块中,websocketpp支持http协议和websocket协议,需要实现的是http请求处理回调函数和websocket请求处理回调函数。其中,HTTP请求的处理回调函数包含了静态资源请求处理、用户注册请求处理、用户登录请求处理和用户信息请求处理。websocket请求处理回调函数包含游戏大厅、游戏房间等长连接的请求处理。
session管理模块:封装session管理,实现http客户端通信状态的维护及身份识别。
session管理模块是用于在浏览器中保存用户的通信状态和身份识别的,当用户在注册或登录后,进入了游戏大厅或游戏房间,那么将会永久保存其Cookie,当用户断开连接后,在一定的时间内,他的Cookie就会被销毁,在登录时需要重新输入账号密码。
在线用户管理模块:对于进入游戏大厅&游戏房间的长连接通信进行管理,实现随时能够获取客户端连接进行消息的主动推送。
在线用户管理模块的作用是将用户id与游戏大厅或游戏房间连接起来,在建立了websocket长连接后,将玩家加入到游戏大厅或游戏房间。当游戏结束,将玩家从游戏房间移除,当玩家退出客户端后,websocket连接断开,将玩家从游戏大厅移除。除此之外,还需要实现判断用户是否在线,即在游戏大厅中或游戏房间中,还需要通过玩家用户id去获取游戏大厅/游戏房间管理对应的通信连接。
游戏房间管理:对于同一个房间中的用户及动作进行处理(对战匹配,下棋,聊天,退出)。
在游戏房间中,游戏房间包含了房间id,玩家数量,房间状态、黑棋白棋玩家的id,以及棋盘,在线用户管理和数据模块管理的指针等字段。在游戏房间中,需要实现的是下棋的动作、处理下棋动作、处理聊天动作和处理玩家退出房间的动作,以及将动作处理广播给房间的所有玩家的方法。
游戏房间管理是需要实现的是对房间的管理,因此需要一个房间的计数器、需要实现的是创建一个游戏房间,通过房间id获取房间信息,通过用户id获取所在的房间的信息,删除房间等方法。
对战匹配管理:将所有玩家根据分数进行等级划分,进行不同等级的对战匹配。
匹配对战分有三个段位:普通、高手和大神三种段位,分别使用三个匹配队列进行玩家的匹配队列的进入等待,并且使用三个线程,异步高效地处理三种玩家的匹配对战。
对于匹配队列来说,不是使用队列,而是使用双向链表来作为匹配队列。匹配队列需要的功能是:出队入队、阻塞线程、移除指定元素等功能。
对于匹配队列的管理,需要实现将玩家进行入队,出队等操作。
将6个模块整合起来,在服务器中进行业务处理:通过网络通信获取到客户端的请求,提供不同的业务处理。
前置知识的学习:
1.websocketpp的学习和使用。
本项目中,使用websocketpp来搭建服务器,因为websocketpp同时支持http和websocket。在本项目中,HTTP用于注册、登录等服务请求中提供短链接服务。而websocket用于在游戏大厅或游戏房间中,提供长连接,并且服务器主动发送消息给客户端的服务。下面链接是关于websocket的介绍以及使用websocketpp搭建简单服务器的框架:
websocket协议
我在做项目时的难点:①HTTP请求响应和websocket请求响应的区别。②服务器搭建流程。③为什么连接句柄是使用lib::weak_ptr管理起来,而不是使用lib::shared_ptr来管理。
解决:
①TTP请求响应和websocket请求响应的区别:
HTTP请求回调处理函数主要是处理来自客户端的HTTP请求,它从连接对象中获取HTTP请求的正文,并通过请求对象获取URI和方法等信息,然后根据不同的方法和URI来进行相应的处理,最后构建HTTP响应对象并发送回客户端。HTTP是一种无状态协议,每个请求都是独立的。
WebSocket消息处理回调函数主要是处理来自客户端的WebSocket消息,它从连接对象中获取WebSocket消息的内容,并进行相应的处理逻辑。不像HTTP请求那样需要获取URI和方法等信息,WebSocket是一种双向通信协议,服务器和客户端可以在持久连接上进行实时双向通信。这个回调函数通过使用连接对象的 send 方法直接将响应消息发送回客户端。
②服务器搭建流程:先实例化出websocketpp的server类对象,通过server类对象设置日志等级、调度器、四种处理回调函数、进入监听状态、获取客户端新连接,最后启动服务器。
③为什么连接句柄是使用lib::weak_ptr管理起来,而不是使用lib::shared_ptr来管理。
hdl是wssrv.start_accept()创建出来的连接对象的引用,他们两者会有互相引用的关系,如果使用了lib::weak_ptr来管理hdl,就不会发生内存泄漏。
MySQLClient库
JsonCpp
模块开发
数据库代码
数据库设计这边,玩家的信息包含了玩家的用户id、用户名、用户密码、天梯分数、排位总场次和胜场总场次。其中,用户id作为主键,并且是自增长的,而用户名和用户密码不能为空,且用户名唯一。根据这个需求,写出以下代码:
drop database if exists online_gobang;
create database if not exists online_gobang;
use online_gobang;
create table if not exists user(id int primary key auto_increment comment '用户id',username varchar(32) unique key not null comment '用户名',password varchar(128) not null comment '用户密码',score int comment '分数',total_count int comment '总场次',win_count int comment '胜利场次'
);
日志打印
#ifndef _M_LOGGER_H_
#define _M_LOGGER_H_
#include<stdio.h>
#include<time.h>//正常
#define INF 0
//调试信息
#define DBG 1
//错误信息
#define ERR 2//strftime:将时间转换为指定格式的字符串
#define LOG(level,format,...) do{\time_t t = time(NULL);\struct tm *lt = localtime(&t);\char buf[32];\strftime(buf,21,"%H:%M:%S",lt);\fprintf(stdout,"[%s %s:%d] " format "\n",buf,__FILE__,__LINE__,##__VA_ARGS__);\
}while(0)#define ILOG(format,...) LOG(INF,format,##__VA_ARGS__);
#define DLOG(format,...) LOG(DBG,format,##__VA_ARGS__);
#define ELOG(format,...) LOG(ERR,format,##__VA_ARGS__);
工具类模块开发
工具类模块开发代码
数据管理模块开发
数据管理模块开发代码
在测试代码的时候,发现插入的数据长度太长,也就是密码在被加密之后,长度超过了我原本设置的password varchar(32)。因此,我需要将其改成varchar(128),并且重新导入:
[wjmhlh@VM-12-9-centos myspace]$ mysql -uroot -p < online_gobang.sql --重新导入
Enter password:
[wjmhlh@VM-12-9-centos myspace]$ mysql -uroot -p
Enter password: Database changed
mysql> desc user;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(32) | NO | UNI | NULL | |
| password | varchar(128) | NO | | NULL | |
| score | int(11) | YES | | NULL | |
| total_count | int(11) | YES | | NULL | |
| win_count | int(11) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)mysql> select * from user;
+----+----------+-------------------------------------------+-------+-------------+-----------+
| id | username | password | score | total_count | win_count |
+----+----------+-------------------------------------------+-------+-------------+-----------+
| 1 | xiaoming | *E56A114692FE0DE073F9A1DD68A00EEB9703F3F1 | 1000 | 0 | 0 |
+----+----------+-------------------------------------------+-------+-------------+-----------+
1 row in set (0.00 sec)
在线用户管理模块开发
在线用户管理模块开发代码
在实现代码中,需要注意的是,当websocket的长连接断开后,我在移除游戏大厅或游戏房间的在线用户管理的uid时,而由于是使用unordered_map作为容器,因此与之对应的通信连接conn就会失去一个映射关系,而通信连接使用了uinque_ptr进行管理,计数器直接减为0,这个通信连接就会自动销毁。
房间管理模块开发
房间管理模块开发代码
session管理模块开发
session管理模块开发
游戏对战匹配模块开发
匹配对战模块开发代码
服务器网络通信模块开发
服务器网络通信模块开发
项目总结
1. 为什么做这个项目
为什么做这个C++五子棋对战网页版的项目,我总结了三点:
①我学习了网络编程,比如HTTP、socket编程等,还没有通过项目实践过,开发经验不足,因此我需要做一个关于网络通信连接的项目来加深我对网络编程的理解和使用。
②我是学习C++的一名计算机专业的学生,对自己掌握的C++的程度,需要有项目的实践操作去检验自己的学习成果。
③在之前学习计算机技术,实践都是通过从一些做题网站中,去做题目来检验自己对知识的掌握,以及写代码的能力,但是却没有过去写一个项目来检验自己的代码逻辑和写代码的能力的,而这个项目的开发,能够很好地检验我自己的代码逻辑和写代码的能力。
2. 项目中都用到了那些技术
在项目中,主要运用到了websocket协议和HTTP协议,以及C++11中的一些新特性,比如包装器,bing方法,互斥锁、智能指针等等,还有就是使用到了STL,比如vector、list、unordered_map等,以及是g++/gcc,makefile,vim/vscode等。
3. 讲一下项目都有那些功能,大概是怎么实现的
在线五子棋对战网页版,主要的功能有:让用户通过浏览器访问服务器,从而实现用户注册,用户登录,对战匹配,实时对战和实时聊天功能。
实现的大概思路是:
实现了6个模块,第一个模块是数据管理模块,这个模块是基于MySQL数据库进行数据管理,并且封装了MySQL的C语言接口,来进行数据管理。第二个模块是在线用户管理模块,这个模块对于进入了的游戏大厅和游戏房间的长连接通信进行管理,通过用户的uid与相对于的客户端的通信连接建立起映射关系,服务器可以实现随时获取客户端通信连接进行消息的主动推送。第三个模块是房间管理模块,在这个模块里面,先是实现了房间类,在房间类中,实现了下棋、聊天等动作,而再实现了一个房间管理的类,通过房间的管理,可以进行房间的创建、销毁、通过用户的id获取房间信息,通过房间id获取房间信息等功能。第四个模块是session模块,这个模块封装了session的管理,实现了HTTP通信连接中客户端通信状态的维护和登录或进入游戏大厅或游戏房间时进行身份识别。第五个模块是游戏对战匹配模块,在这个模块里面是将所有玩家根据分数吗,进行了档次的划分,使用多线程,分别对同档次的玩家进行不同的对战匹配。第六个模块是网络服务器的模块开发,在这个模块里面,是基于了websocketpp来搭建了服务器,实现了与客户端进行通信的功能。
4. 做的时候遇到过什么问题,当时是怎么想的,最后是怎么解决的
在做项目的过程中,遇到了不少的技术问题。
①比如在使用websocketpp协议的时候,一开始的时候没有掌握好HTTP协议和websocket协议的使用,比如说在接受请求和发送响应,它们是有区别的。一开始以为在响应的时候,需要获取uri和方法,然后根据uri和方法将那些响应的。然后当时在网上查了文档,别人写的文章,还问了一些类似chargpt的ai,最后才发现,原来websocket不需要获取请求中的uri,可以直接通过send方法给客户端做出响应。
②一开始在设计user表的时候,我把密码的长度设置了32个字符长度。开始的时候,我给用户注册密码都是6位,我没弄清楚为什么在报错的时候,提示我是密码长度超出了设置的长度。于是我在MySQL的客户端上,重新查看了describe user命令查看了表结构,发现是32位,然后我于是通过SHOW VARIABLES LIKE 'validate_password%'命令,去查看密码等级的设置,并没有出现设置不匹配的原因,后来我查了很多资料,问了老师,才知道,是在密码加密之后,密码长度会变长,于是我就设置成128位。
5. 项目中最难的一个知识点
我认为,在这个项目中最难的一个知识点是对于如何去使用websocketpp去搭建服务器这个点上。因为在做这个项目之前,我都只用过HTTP去做过一个简单的服务器,没有拓展到去学习websocket协议,从而使用websocket去搭建一个拥有HTTP协议和websocket协议的服务器。
6. 有想过怎么扩展吗
想过给下棋玩家设置一个时间限制,在规定时间内没有下棋动作,那么就直接轮到对方下棋。
还有就是增加一个AI选手,可以让玩家与AI进行对战。
项目整体代码链接
代码链接
相关文章:

C++项目:在线五子棋对战(网页版)
项目介绍 本项⽬主要实现⼀个⽹⻚版的五⼦棋对战游戏,其主要⽀持以下核⼼功能: • 用户管理:实现用户注册,用户登录、获取用户信息、用户天梯分数记录、用户比赛场次记录等。 • 匹配对战:实现两个玩家在网页端根据天梯分数匹配游戏对⼿&…...
flutter遇到的小问题记录
flutter-getx的Get.bottomSheet组件改变高度 Get.bottomSheet( isScrollControlled: true,) isScrollControlled: true 就是控制高度 (无语) 截取视频第一针 返回的是本地url 或者Uint8List的数据 String? videoStr await VideoThumbnail.thumbnailFile(video: videoPath,…...

Golang bitset 基本使用
安装: go get github.com/bits-and-blooms/bitset下面代码把fmtx换成fmt就行 //------------基本操作------------//构建一个64bit长度的bitsetb : bitset.New(64)//放入一个数b.Set(10)fmtx.Println("add-10:", b.DumpAsBits()) // 0000000…...
sql 分组讨论,二级分组(非2个字段分组),使用 窗口函数和普通分组实现
1. 二级分组需求 先按照一个字段分组,在按照 第二个字段分组。之后,如果 这个 二级分组中的数据,是 > 1条的。就筛选出来。 比如: 先按照 站点分组,再按照 设备分组, 即:如果站点上配置了…...

业务中如何过滤敏感词
在我们访问网站的时候,如果发现我们发布的内容有色情暴力的东西等等,会屏蔽掉,这种行为就是过滤敏感词。 从技术层面实现起来,其实比较简单,因为我们输入的内容就是一个大型的字符串,我们要调用某些api来判…...
用服务器搭建网站需要做什么
网站建设是一个广义的术语,涵盖了许多不同的技能和学科中所使用的生产和维护的网站。不同领域的网页设计,网页图形设计,界面设计,创作,其中包括标准化的代码和专有软件,用户体验设计和搜索引擎优化。许多人…...

clickhouse 删除操作
OLAP 数据库设计的宗旨在于分析适合一次插入多次查询的业务场景,市面上成熟的 AP 数据库在更新和删除操作上支持的均不是很好,当然 clickhouse 也不例外。但是不友好不代表不支持,本文主要介绍在 clickhouse 中如何实现数据的删除,…...

C 语言中,「.」与「->」有什么区别?
使用“.”的话,只需要声明一个结构体。格式是结构体类型名结构体名。然后通过结构体名加上“.”再加上域名,就可以引用结构体的域了。因为结构体的内存是自动分配的,就像使用int a;一样。而使用“->”的话,需要声明一个结构体的…...

github pages 用法详解 发布自己的网站
github pages 基础用法 URL 规则 假设你的 github 帐号为 mygithub,需要发布的仓库名为 myrepo,那么 pages 的 URL 为: https://mygithub.github.io/myrepo 添加内容 用任意编辑器写好(或者生成)标准的网页内容&a…...

坤简炫酷的JQuery轮播图插件
介绍: 找到了一个炫酷的JQuery轮播图插件,只需要配置三四行代码就可以实现很多二维三维炫酷的切换效果。 视频效果及教程: https://www.bilibili.com/video/BV1Fu4y1d776/ 代码: https://github.com/w-x-x-w/AwesomeWeb 使用…...
C# 条件编译
C# 条件编译 C# 条件编译:根据不同的需求,编译生成不同的程序版本,条件编译是一种编译预处理命令,它是在编译代码之前对源代码进行处理。它可以根据条件,决定是否编译某段代码 条件编译的三种形式: 第一种…...

IntelliJ IDEA如何重新弹出git身份验证窗口
1、点击File菜单—>点击Settings—>点击Appearance & Behavior—>点击System Settings—>点击Passwords—>选中Do not save, forget passwords after restart—>点击Apply—>点击OK,如下所示: 2、重启IntelliJ IDEA—>通过g…...

【雕爷学编程】Arduino动手做(200)---WS2812B幻彩LED灯带4
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…...

【雕爷学编程】Arduino动手做(201)---DFRobot 行空板03
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…...

Spring中Bean的“一生”(生命周期)
文章目录 一、图解二、文字解析总结 一、图解 >注:处于同一行的执行顺序是从左往右 二、文字解析 SpringBean的生命周期总体分为四个阶段:实例化>属性注入>初始化>销毁 Step1 实例化Bean:根据配置文件中Bean的定义,…...

安卓:LitePal操作数据库
目录 一、LitePal介绍 常用方法: 1、插入数据: 2、更新数据: 3、删除数据: 4、查询数据: 二、LitePal的基本用法: 1、集成LitePal: 2、创建LitePal配置文件: 3、创建模型类…...

【JavaEE初阶】了解JVM
文章目录 一. JVM内存区域划分二. JVM类加载机制2.1 类加载整体流程2.2 类加载的时机2.3 双亲委派模型(经典) 三. JVM垃圾回收机制(GC)3.1 GC实际工作过程3.1.1 找到垃圾/判定垃圾1. 引用计数(不是java的做法,Python/PHP)2. 可达性分析(Java的做法) 3.1.2 清理垃圾1. 标记清除2…...
基于vue2.0和elementUi的vue农历日期组件vue-jlunar-datepicker(插件)
vue-jlunar-datepicker(插件) vue实现农历日历插件——vue-jlunar-datepicker插件 这个插件本身是基于vue2.0和elementUi框架来实现的。 安装 vue-jlunar-datepicker 插件 npm install vue-jlunar-datepicker --save // 如果安装过程中,出现…...
Python爬虫——selenium_元素定位
元素定位:自动化要做的就是模拟鼠标和键盘来操作这些元素,点击,输入等等。操作这些元素前首先要找到它们,WebDriver提供很多定位元素的方法 from selenium import webdriver# 创建浏览器对象 path files/chromedriver.exe brows…...

短视频内容平台(如TikTok、Instagram Reel、YouTube Shorts)的系统设计
现在,短视频内容已成为新趋势,每个人都在从TikTok、Instagram、YouTube等平台上消费这些内容。让我们看看如何为TikTok创建一个系统。 这样的应用程序看起来很小,但在后台有很多事情正在进行。以下是相关的挑战: •由于该应用程序…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...