【五子棋在线对战】三.数据管理模块实现

news2025/6/9 19:38:28

数据管理模块实现

  • 1.数据库表的设计
  • 2.数据管理模块的封装和实现
    • 2.1 user_table() && ~user_table()
    • 2.2 insert() 注册时新增用户
    • 2.3 login() 登录验证,并返回详细的用户信息
    • 2.4 通过用户名获取用户信息 && 通过用户id获取用户信息
    • 2.5 win() && lose()

项目链接: 五子棋项目

1.数据库表的设计

在数据库表的成员变量中,除了id,用户名,密码之外,还有一些是是针对于游戏中的设计

  1. id
  2. username
  3. password
  4. score:分数
  5. total_count:总场数
  6. win_count:赢的场数
create database if not exists gobang;
use gobang;
create table if not exists user(
    id int primary key auto_increment,
    username varchar(32) not null,
    password varchar(32) not null,
    score int,
    total_count int,
    win_count int 
);

2.数据管理模块的封装和实现

实现一个mysql客户端来访问服务器进行数据的操作,为了项目的可拓展性,针对管理的每一张表都去设计一个类,我们这里是针对用户的数据所以设计的就是user类
在这里插入图片描述
这里的函数实现要搭配着上一篇文章实现的使用工具类中的mysql_util这个类。

2.1 user_table() && ~user_table()

user_table的初始化就是mysql_create()要传入的参数也是mysql_create这个函数所需要的参数,析构函数就直接调用mysql_destroy即可。

2.2 insert() 注册时新增用户

这里就是简单的使用sql语句即可,要对用户和密码不全的情况进行判断

     bool insert(Json::Value &user)
     {
#define INSERT_USER "insert user values(null, '%s', '%s', 1000, 0, 0);"
          //密码用户不全
          if (user["password"].isNull() || user["username"].isNull())
          {
               DLOG("INPUT PASSWORD OR USERNAME");
               return false;
          }
          char sql[4096] = {0};
          // sprintf(void *buf, char *format, ...)
          sprintf(sql, INSERT_USER, user["username"].asCString(), user["password"].asCString());
          bool ret = mysql_util::mysql_exec(_mysql, sql);
          if (ret == false)
          {
               DLOG("insert user info failed!!\n");
               return false;
          }
          return true;
     }

2.3 login() 登录验证,并返回详细的用户信息

mysql链接共享,所以在多个线程同时执行sql语句时会导致竞争,所以需要加锁保护,这里有一个新的写法在加锁的地方用括号括起来,这样就变成了一个区间,区间结束之后锁会自动释放。

          {
               std::unique_lock<std::mutex> lock(_mutex);
               bool ret = mysql_util::mysql_exec(_mysql, sql);
               if (ret == false)
               {
                    DLOG("user login failed!!\n");
                    return false;
               }
               // 要么有数据,要么没有数据,就算有数据也只能有一条数据
               res = mysql_store_result(_mysql);
               if (res == NULL)
               {
                    DLOG("have no login user info!!");
                    return false;
               }
          }

2.4 通过用户名获取用户信息 && 通过用户id获取用户信息

这两个的函数几乎一模一样,就是在sql查询语句中的查询条件不同

     bool select_by_name(const std::string &name, Json::Value &user)
     {
#define USER_BY_NAME "select id, score, total_count, win_count from user where username='%s';"
          char sql[4096] = {0};
          sprintf(sql, USER_BY_NAME, name.c_str());
          MYSQL_RES *res = NULL;
          {
               std::unique_lock<std::mutex> lock(_mutex);
               bool ret = mysql_util::mysql_exec(_mysql, sql);
               if (ret == false)
               {
                    DLOG("get user by name failed!!\n");
                    return false;
               }
               // 要么有数据,要么没有数据,就算有数据也只能有一条数据
               res = mysql_store_result(_mysql);
               if (res == NULL)
               {
                    DLOG("have no user info!!");
                    return false;
               }
          }
          int row_num = mysql_num_rows(res);
          if (row_num != 1)
          {
               DLOG("the user information queried is not unique!!");
               return false;
          }
          MYSQL_ROW row = mysql_fetch_row(res);
          user["id"] = (Json::UInt64)std::stol(row[0]);
          user["username"] = name;
          user["score"] = (Json::UInt64)std::stol(row[1]);
          user["total_count"] = std::stoi(row[2]);
          user["win_count"] = std::stoi(row[3]);
          mysql_free_result(res);
          return true;
     }

2.5 win() && lose()

这也类似,一个是加分一个是减分

  1. 胜利时天梯分数增加30分,战斗场次增加1,胜利场次增加1
  2. 失败时天梯分数减少30,战斗场次增加1,其他不变
     bool win(uint64_t id)
     {
#define USER_WIN "update user set score=score+30, total_count=total_count+1, win_count=win_count+1 where id=%ld;"
          char sql[4096] = {0};
          sprintf(sql, USER_WIN, id);
          bool ret = mysql_util::mysql_exec(_mysql, sql);
          if (ret == false)
          {
               DLOG("update win user info failed!!\n");
               return false;
          }
          return true;
     }

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

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

相关文章

【JMeter】后置处理器 - 提取器

文章目录 概览边界提取器正则提取器JSON提取器 概览 CSS/JQuery提取器&#xff1b;给网页使用JSON提取器&#xff1a;给JSON数据使用★边界提取器&#xff1a;给字符串使用★正则表达式提取器&#xff1a;更加高级的字符使用★Xpath提取器&#xff1a;给网页使用 边界提取器…

OpenAI技术路线急转:从TypeScript到Rust的Codex CLI重构内幕

目录 前言&#xff1a;OpenAI的技术抉择引发业界思考 Codex CLI&#xff1a;OpenAI的终端AI编程利器 语言抉择的戏剧性反转&#xff1a;从TypeScript到Rust Rust重写的四大技术动因 1. 零依赖部署&#xff1a;消除环境配置痛点 2. 内存安全与沙箱隔离 3. 性能的全面碾压 …

window下配置ssh免密登录服务器

window下配置ssh免密登录服务器 本地windows远程登录我的ssh服务器10.10.101.xx服务器&#xff0c;想要每次都免密登录这个服务器. 记录下教程&#xff0c;防止后期忘记&#xff0c;指导我实现这个过程。 教程 二、实践步骤&#xff1a;Windows 上配置 SSH 免密登录 2.1 确…

nginx部署

配置阿里云yum源 安装如下编译工具 yum install -y gcc gcc-c autoconf automake make #安装使用nginx还得安装nginx所需的一些第三方系统库的支持&#xff0c;比如nginx的静态资源压缩功能所需的gzip lib库&#xff0c;nginx需要支持URL重写&#xff0c;所需的pcre库&…

线性规划饮食问题求解:FastAPI作为服务端+libhv作为客户端实现

之前在 Pyomo介绍-CSDN博客 中介绍过通过Pyomo求解线性规划问题&#xff0c;这里使用FastAPI作为服务端&#xff0c;开源网络库libhv作为客户端&#xff0c;求解饮食成本最小化问题。 服务端测试代码test_fastapi_pyomo_server.py如下&#xff1a; from fastapi import FastAP…

前端验证下跨域问题(npm验证)

文章目录 一、背景二、效果展示三、代码展示3.1&#xff09;index.html3.2&#xff09;package.json3.3&#xff09; service.js3.4&#xff09;service2.js 四、使用说明4.1&#xff09;安装依赖4.2&#xff09;启动服务器4.3&#xff09;访问前端页面 五、跨域解决方案说明六…

Linux Docker的简介

参考资料 30分钟Docker入门教程 ◀ 本篇博客所有图片皆来自于该视频截图阮一峰 - Docker 入门教程 目录 一. 环境配置时可能会遇到的问题二. 什么是Docker三. 虚拟机 与 Docker 的区别3.1 虚拟机3.2 Docker 四. Docker的基本架构五. Dockerfile 一. 环境配置时可能会遇到的问题…

极昆仑智慧与数元灵科技达成战略合作

近日&#xff0c;北京极昆仑智慧科技有限公司与北京数元灵科技有限公司正式签署产品级融合战略合作协议&#xff0c;双方将围绕 "AIBI商业智能分析" " Hybrid RAG 大模型问答" 等核心大模型应用&#xff0c;实现技术架构与业务场景的深度集成&#xff0c;…

第四讲:类和对象(下)

1. 再探构造函数 • 之前我们实现构造函数时&#xff0c;初始化成员变量主要使⽤函数体内赋值&#xff0c;构造函数初始化还有⼀种⽅ 式&#xff0c;就是初始化列表&#xff0c;初始化列表的使⽤⽅式是以⼀个冒号开始&#xff0c;接着是⼀个以逗号分隔的数据成 员列表&#xff…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Dad Jokes(冷笑话卡片)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— DadJokes 组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ 豆包翻译确实可以&#xff0c;冷笑话应该属于各类语言比较难理解的…

Spring AOP执行原理源码解析

对【com.example.demo.TestAspect#aopTest】连接点增加了五个通知 在调用【com.example.demo.A#testAop()】&#xff08;用户自定义&#xff09;方法时&#xff0c;Cglib拦截器对其进行了拦截 可以看到执行顺序分别是环绕前置&#xff0c;前置&#xff0c;环绕后置&#xff0c;…

基于FPGA的超声波显示水位距离,通过蓝牙传输水位数据到手机,同时支持RAM存储水位数据,读取数据。

基于FPGA的超声波显示水位距离 前言一、整体框架二、代码架构1.超声波测距模块2.蓝牙数据发送模块3.数码管数据切换模块4.数码管驱动模块6.串口驱动7.顶层模块8.RAM ip核 仿真相关截图 前言 随着工业化进程的加速和环境保护意识的提升&#xff0c;对水资源管理和水位监测的需求…

在Windows下利用LoongArch-toolchain交叉编译Qt

文章目录 0.交叉编译的必要性1.下载交叉编译工具链1.1.直接在Windows下使用mingw&#xff08;不使用虚拟机&#xff09;编译&#xff08;还没成功&#xff0c;无法编译&#xff09;1.2.在虚拟机中的Ubuntu中进行交叉编译 2.下载qt源码3.编译Qt3.1.创建loongarch64的mkspec3.2.创…

AIRIOT无人机安防解决方案

随着无人机技术的飞速发展和广泛应用&#xff0c;其在安防领域的价值日益凸显&#xff0c;从关键设施巡检、大型活动安保到边境巡防、应急救援&#xff0c;无人机正成为立体化安防体系不可或缺的“空中哨兵”。然而&#xff0c;无人机安防应用蓬勃发展的同时&#xff0c;其自身…

华为OD机考 - 水仙花数 Ⅰ(2025B卷 100分)

import java.util.*; public static Integer get(int count,int c){if(count<3||count>7){return -1;}//存储每位数的最高位……最低位int[] arr new int[count];List<Integer> res new ArrayList<>();for(int i(int) Math.pow(10,count-1);i<(int) Math…

php apache构建 Web 服务器

虚拟机配置流程winsever2016配置Apache、Mysql、php_windows server 2016配置web服务器-CSDN博客 PHP 和 Apache 通过 ​​模块化协作​​ 共同构建 Web 服务器&#xff0c;以下是它们的交互机制和工作流程&#xff1a; ​​一、核心组件分工​​ 组件角色​​Apache​​Web …

打通印染车间“神经末梢”:DeviceNet转Ethernet/IP连接机器人的高效方案

在印染行业自动化升级中&#xff0c;设备联网需求迫切。老旧印染设备多采用Devicenet协议&#xff0c;而新型工业机器人普遍支持Ethernet/IP协议&#xff0c;协议不兼容导致数据交互困难&#xff0c;设备协同效率低、生产监控滞后&#xff0c;成了行业数字化转型的阻碍。本文将…

2025-06-02-IP 地址规划及案例分析

IP 地址规划及案例分析 参考资料 Plan for IP addressing - Cloud Adoption Frameworkwww.cnblogs.comimage-hosting/articles at master jonsam-ng/image-hosting 概述 在网络通信中&#xff0c;MAC 地址与 IP 地址分别位于 OSI 模型的数据链路层和网络层&#xff0c;二者协…

AUTOSAR实战教程--开放式通用DoIP刷写工具OpenOTA开发计划

目录 软件概述 安装与运行 界面说明 3.1 功能区划分 3.2 状态显示 基本操作流程 4.1 DoIP连接配置 4.2 服务配置&#xff08;刷写流程&#xff09; 4.3 执行操作 4.4 保存配置 4.5 加载配置 功能详解 5.1 核心功能模块 诊断服务配置 通信设置 文件下载 工具功…

AI赋能的浏览器自动化:Playwright MCP安装配置与实操案例

以下是对Playwright MCP的简单介绍&#xff1a; Playwright MCP 是一个基于 Playwright 的 MCP 工具&#xff0c;提供浏览器自动化功能不要求视觉模型支持&#xff0c;普通的文本大语言模型就可以通过结构化数据与网页交互支持多种浏览器操作&#xff0c;包括截图、点击、拖动…