C语言 #具有展开功能的排雷游戏
文章目录
前言
一、整个排雷游戏的思维梳理
二、整体代码分布布局
三、游戏主体逻辑实现--test.c
四、整个游戏头文件的引用以及函数的声明-- game.h
五、游戏功能的具体实现 -- game.c
六、老六版本
总结
前言
路漫漫其修远兮,吾将上下而求索。
一、整个排雷游戏的思维梳理
当玩家点开游戏,就会出现菜单供玩家进行选择,是玩游戏还是退出游戏(当然,你还可以整点有意思的选项,让正经的排雷游戏变得不正经);
当玩家输入自己的选择后,要么退出游戏,要么进入排雷游戏;当玩家进入排雷游戏时,就要先给玩家展示一下棋盘,让玩家输入想要排查的坐标,计算机再判断玩家输入的这个坐标是不是'雷',如果是雷,游戏结束;当然菜单会再出现一次,玩家可自行判断要不要再来一局游戏;如果不是雷就要向玩家展示此坐标周围雷的个数,并且玩家会一直输入坐标进行排雷直到玩家踩到雷或者玩家排雷成功;
感觉不难,让我们一起来实现吧~
二、整体代码分布布局
明确分工,提高效率~
test.c //整个游戏的主题逻辑
game.c //游戏功能的具体实现
game.h //包含一些头文件以及函数进行函数声明
三、游戏主体逻辑实现--test.c
代码如下:
#include"game.h"void menu()
{printf("****************************\n");printf("*****1、 play **************\n");printf("*****0、 exit **************\n");printf("****************************\n");
}
void game()
{//创建棋盘--二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };//初始化棋盘InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');//电脑随机放雷SetMine(mine, ROW, COL);//向玩家展示所要排雷的棋盘DisplayBoard(show, ROW, COL);//玩家排雷FindMine(mine, show, ROW, COL);
}
int main()
{int input = 0;do{menu();printf("玩家请输入选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏成功\n");break;default :printf("输入错误,请重新输入\n");}} while (input);return 0;
}
注意:
1、 为什么创建了两个数组,并且都是字符数组
由于在 show 展示的棋盘上我们想要用 * 来初始化此棋盘,显然show 棋盘中底层用来存放数据的二维数组就应该是字符数组;如果要将雷的信息放在show 中,那么显示给玩家看也会一览无余雷的位置,所以这里应该创建两个相同的“棋盘”,一是用来专门存放电脑随机分配的雷的信息以及排雷,另外一个就是展示给玩家看的,实现与玩家的互动;那么这两个棋盘在类型与大小上保持一致就会更好操作,当然你也可以不让这两个数组一样,只不过是在处理上会更加麻烦了而已
2、数组的创建为什么用ROWS 与 COLS创建呢,而展示却是用ROW 与 COL
在头文件game.h 中,ROW ,COL 是我们定义的标识符常量即为9,而ROWS,COLS 在ROW ,COL 的基础上大了2;
创建的棋盘比实际的棋盘的横列均多2 的原因是,在排雷的时候,如果玩家输入的坐标不是雷的话,就要计算该坐标周围雷的个数;如果是计算边缘坐标周围的雷的个数,周围的坐标数都不同,所以为了统一处理,保证实际棋盘中的每个做坐标周围均有8个坐标;(当然你也可以不这样做,头铁的话只有麻烦自己了)
3、既然为字符数组是如何求得非雷坐标周围雷的个数的?
例如如果非雷用‘ ’ 来表示,雷用 ‘*’ 来表示,利用循环产生包括此非雷坐标的9个坐标,一个个判断产生的 坐标再判断是不是雷'*' 即可,是雷的话便利用计数器 count++ 即可;本文写的代码中,非雷为 ‘0’ ,雷为 ‘1’ ,由于字符本质上就是ASCII码值,所以也可以利用那么可以用加法与减法的原则来计算周围坐标雷的个数(当然,我用的是循环+计数器);
4、电脑随机放置雷的操作的原理
在此之前,我们得了解一下rand srand time;
rand 与 srand 的头文件 <stdlib.h>
time 的头文件 <time.h>
int rand(void); 库函数rand 没有参数,但是有返回值,其返回值类型为int;
库函数可以生成随机数,但是它是基于算法生成得,故而并不是真正的随机数,是伪随机数;rand 生成伪随机数的范围为 0-32767;
而使用rand 一般是要与srand 一起使用的;srand产生随机变化的数seed(种子), 而rand 是基于srand 产生的数即seed(种子)进行产生伪随机数算法的运算;当使用rand 的程序中没有srand时,rand 便会默认种子为1;
void srand( unsigned int seed) ;库函数的参数类型为 unsigned int,如若想让rand 基于 seed产生随机的值,那么这个seed 就得变化。而什么是变化的呢?聪明的你可能会说是时间!没错,真棒,就是时间;我们可以利用时间戳,即利用库函数 time ;
注:时间戳:当前时间与计算机时间 1970年1月1日午夜之间的差值(单位是秒);
time_t time (time_t * timer);
库函数 time 的返回类型为 time_t ,其参数为 time_t* 类型的指针;
即如果正常使用库函数time ,得有指针参数,time 会返回一位 time_t 类型的返回值;如果不想用time 的参数,那么就用空指针NULL;
只要每一次程序运行是 seed 都不同,那么便可以保证 rand 在每一次程序执行时产生的随机值不会有相同;所以将 seed 产生放在main 函数中即可;
5、玩家排雷--展开操作的原理
说“展开”,可能你还不知道是什么意思;你玩排雷游戏的时候,是不是有时会展开一片呢?展开这一片的功能就是此处探讨的展开功能;如下图所示:
展开的格子,是非雷且周围没有雷;--> 这里便包含了两个条件
当周围8个坐标有雷的时候,就不会展开为空格,取而代之的是标明此坐标周围雷的个数;
图解:
分析:当玩家输入一个坐标的时候,首先要判断此坐标是否在排雷对象棋盘的合理范围之内;在合理范围之内便进行上图的操作;会用到三个功能,一是计算一个坐标周围雷的个数,二是展开空格的功能,三是判断玩家输赢;
四、整个游戏头文件的引用以及函数的声明-- game.h
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>#define ROW 9
#define COL 9#define ROWS ROW+2
#define COLS COL+2#define MINE_COUNT 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);//电脑随机放雷
void SetMine(char mine[ROWS][COLS], int row, int col);//计算周围八个坐标雷的个数
int ArroundingMine(char mine[ROWS][COLS], int x, int y);//展开功能
void ExtendBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);//玩家排雷是否成功的判断条件
int IsWin(char show[ROWS][COLS], int row, int col);//向玩家展示所要排雷的棋盘
void DisplayBoard(char show[ROWS][COLS], int row, int col);//玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
分析:
在头文件中实现头文件、函数的声明,以及定义标识符常量,只要源文件声明包含了此头文件,相当于此源文件也声明了一次;
注:1、#define 定义的标识符常量 --> 在全局使用时更易于修改,非常方便;
2、函数一定要做到先声明再使用!
五、游戏功能的具体实现 -- game.c
1、初始化棋盘
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set;}}
}
就是二维数组的初始化,两重循环嘎嘎整起来就可以了!
2、电脑随机放雷
//电脑随机放雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int count = MINE_COUNT;while (count){x = rand() % row + 1;y = rand() % col + 1;//埋雷的范围是1-9if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}
雷坐标的产生并不是每一次都可以产生有效的坐标,且雷坐标的个数受雷个数的影响(此处的 MINE_COUNT 就是在头文件中定义的标识符常量--雷的个数--为10),所以此处应该用循环,并且是用while 循环;
看上面的代码,相信聪明的你一定可以理解!
3、向玩家展示所要排雷的棋盘
//向玩家展示所要排雷的棋盘
void DisplayBoard(char show[ROWS][COLS], int row, int col)
{//展示的show 棋盘上的1-9//还要添上坐标int i = 0;int j = 0;for (j = 0; j <= col; j++){printf("%d ", j);}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", show[i][j]);}//打印完一行就换行printf("\n");}
}
这个函数就有点讲究了,不仅向玩家展示了棋盘,还加上了索引;记得换行记得换行记得换行!!!重要的事情说三遍!
二维数组在内存中是一块连续的空间,如果想打印出规规整整的棋盘样式,就得在每打印完一行之后,写个printf("\n"); 以实现手动换行;
其次就是加上索引:在每一行前加上行数,以表示此行是第几行;显然就会多一列,那么用一行的数字对应此列为第几列时,就应该从0开始;
注意你的目标,你打印的时 show 数组中1-9 行,1-9 列的数据;
4、计算周围八个坐标雷的个数
//计算周围八个坐标雷的个数
int ArroundingMine(char mine[ROWS][COLS], int x, int y)
{int i = 0;int j = 0;int count = 0;for(i = -1; i <= 1; i++){for (j = -1; j <= 1; j++){if (mine[x + i][y + j] == '1')count++;}}return count;
}
原理前面提过,如果不太理解这里的代码可以往前翻翻,不过相信聪明的你一定是理解的;
5、展开功能
//展开功能
void ExtendBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{//产生该坐标周围八个坐标int i = 0;int j = 0;int count = 0;for (i = x-1; i <= x+1; i++){for (j= y-1; j <= y+1; j++){//避免重查if (show[i][j] == '*'){//不是雷if (mine[i][j] == '0'){count = ArroundingMine(mine, i, j);if (count == 0){show[i][j] = ' ';ExtendBoard(mine, show, i, j);}else{show[i][j] = count + '0';}}}}}
}
基本上就是这张图的意思:
注:此处的show[i][j] = count + '0';
因为数组 show 是char 类型的数组,所以其元素是char 类型,然而count = ArroundingMine(mine, i, j); 计算周围坐标雷的个数的函数的ArroundingMine 的返回类型是 int 类型,所以用来接收其返回值的 conut 是 int 类型,想让数字转换成字符,利用ascii码值即可,即加上 '0' ;
6、玩家排雷是否成功的判断条件
//玩家排雷是否成功的判断条件
int IsWin(char show[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;int count = 0;for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){if (show[i][j] == '*')count++;}}return count;
}
7、玩家排雷
//玩家输入想要排查的坐标
// 输入的坐标合法
//避免重查
//在mine 棋盘上判断该坐标是不是雷;是雷,游戏结束;不是雷,游戏继续;
//在此坐标不是雷的基础上,计算该坐标周围雷的个数;如果个数为0,先排除重查的坐标,再计算此坐标周围八个坐标的周围八个坐标的雷的个数
//递归; 如果个数不为0,就在show 棋盘对应的坐标上展示此坐标周围雷的个数
//循环的结束:当玩家踩到雷或者排雷成功
//排雷成功的标准:在show 棋盘上剩下的*个数与雷的个数相同
//玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;int count = 0;win = IsWin(show, ROW, COL);while (win > MINE_COUNT){printf("玩家请输入想要排查的坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (show[x][y] == '*'){if (mine[x][y] == '1'){printf("哎呦,踩到雷了,游戏结束\n");DisplayBoard(mine, ROW, COL);break;}else{count = ArroundingMine(mine, x, y);if (count == 0){ExtendBoard(mine, show, x, y);}else{show[x][y] = count + '0';}win = IsWin(show, ROW, COL);DisplayBoard(show, ROW, COL);}}else{printf("此坐标已经排查过,请重新输入\n");}}else{printf("输入的坐标不再棋盘的范围内,请重新输入\n");}}if (win == MINE_COUNT){printf("恭喜玩家排雷成功\n");DisplayBoard(mine, ROW, COL);DisplayBoard(show, ROW, COL);}
}
六、老六版本
1、老娘费尽心思做的小游戏,发给你,你必须给我玩!不玩就让你电脑关机;
2、可以不让你的电脑关机,但是你得喊我 “爸爸” (叉除、忽略均无效反抗,只要你不输入 “爸爸”,都给你关机)
效果如下:
test.c 代码如下:
#include"game.h"void menu()
{printf("****************************\n");printf("*****1、 play **************\n");printf("*****0、 exit **************\n");printf("*****2、 不玩 **************\n");printf("****************************\n");
}
void game()
{//创建棋盘--二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };//初始化棋盘InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');//电脑随机放雷SetMine(mine, ROW, COL);//向玩家展示所要排雷的棋盘DisplayBoard(show, ROW, COL);//玩家排雷FindMine(mine, show, ROW, COL);
}void punish()
{char input[20] = { 0 };printf("老娘幸幸苦苦做的游戏,你居然不玩\n");Sleep(1000);printf("好好好,必须惩罚你\n");system("shutdown -s -t 60");
again:printf("叫我爸爸,免你电脑不死\n");scanf("%s", &input);if (strcmp(input, "爸爸") == 0){printf("乖,儿子;爸爸这就饶你电脑不死\n");system("shutdown -a");}else{printf("哦呦,有能耐嗦,倒计时了哦~再不喊电脑就关机了喔\n");goto again;}
}
int main()
{int input = 0;do{menu();printf("玩家请输入选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏成功\n");break;case 2:punish();break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}
在game.h 文件多引用两头文件即可:
注:在C语言中,有一个system 函数--> 执行系统命令; 其头文件是 <windows.h>
关机指令: shutdown -s -t 60
其中,shutdown 意为关机; -s --> 设置关机 -t --> 设置倒计时关机 60 --> 代表60秒
没查没搜,我是这样记的: -s --> set 设置 -t --> time 时间
取消关机指令 : shutdown -a
-a --> abandon 放弃
当然,利用好 system("shutdown -s -t 60") 和 system("shutdown -a"),你可以更加老六
总结
完,赶快动手试一试吧!
相关文章:

C语言 #具有展开功能的排雷游戏
文章目录 前言 一、整个排雷游戏的思维梳理 二、整体代码分布布局 三、游戏主体逻辑实现--test.c 四、整个游戏头文件的引用以及函数的声明-- game.h 五、游戏功能的具体实现 -- game.c 六、老六版本 总结 前言 路漫漫其修远兮,吾将上下而求索。 一、整个排…...

npm publish出错,‘proxy‘ config is set properly. See: ‘npm help config‘
问题:使用 npm publish发布项目依赖失败,报错 proxy config is set properly. See: npm help config 1、先查找一下自己的代理 npm config get proxy npm config get https-proxy npm config get registry2、然后将代理和缓存置空 方式一: …...

Springboot 多数据源事务
起因 在一个service方法上使用的事务,其中有方法是调用的多数据源orderDB 但是多数据源没有生效,而是使用的primaryDB 原因 spring 事务实现的方式 以 Transactional 注解为例 (也可以看 TransactionTemplate, 这个流程更简单一点)。 入口:ProxyTransa…...

Python每日学习
我是从c转来学习Python的,总感觉和c相比Python的实操简单,但是由于写c的代码多了,感觉Python的语法好奇怪 就比如说c的开头要有库(就是类似于#include <bits/stdc.h>)而且它每一项的代码结束之后要有一个表示结…...

数据库 执行sql添加删除字段
添加字段: ALTER TABLE 表明 ADD COLUMN 字段名 类型 DEFAULT NULL COMMENT 注释 AFTER 哪个字段后面; 效果: 删除字段: ALTER TABLE 表明 DROP COLUMN 字段;...

前端开发:HTML与CSS
文章目录 前言1.1、CS架构和BS架构1.2、网页构成 HTML1.web开发1.1、最简单的web应用程序1.2、HTTP协议1.2.1 、简介1.2.2、 http协议特性1.3.3、http请求协议与响应协议 2.HTML概述3.HTML标准结构4.标签的语法5.基本标签6.超链接标签6.1、超链接基本使用6.2、锚点 7.img标签8.…...

ctfshow解题方法
171 172 爆库名->爆表名->爆字段名->爆字段值 -1 union select 1,database() ,3 -- //返回数据库名 -1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema库名 -- //获取数据库里的表名 -1 union select 1,group_concat(…...

探索 Blockly:自定义积木实例
3.实例 3.1.基础块 无输入 , 无输出 3.1.1.json var textOneJson {"type": "sql_test_text_one","message0": " one ","colour": 30,"tooltip": 无输入 , 无输出 };javascriptGenerator.forBlock[sql_test_te…...

MongoDB教程(二十三):关于MongoDB自增机制
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、MongoD…...

展馆导览系统架构解析,从需求分析到上线运维
在物质生活日益丰富的当下,人们对精神世界的追求愈发强烈,博物馆、展馆、纪念馆等场所成为人们丰富知识、滋养心灵的热门选择。与此同时,人们对展馆的导航体验也提出了更高要求,展馆导览系统作为一种基于室内外地图相结合的位置引…...

Servlet详解(超详细)
Servlet详解 文章目录 Servlet详解一、基本概念二、Servlet的使用1、创建Servlet类2、配置Servleta. 使用web.xml配置b. 使用注解配置 3、部署Web应用4、处理HTTP请求和生成响应5、处理表单数据HTML表单Servlet 6、管理会话 三、servlet生命周期1、加载和实例化2、初始化3、 请…...

Meta AI引入Imagine Me功能,上传图片输入提示词即可实现个性化照片
AITOP100平台获悉,Meta 公司在 AI 领域再次迈出了重要的步伐,其发布的 Llama 3.1 开源 AI 模型以及对 Meta AI 功能的更新扩充引发了广泛关注。 其中,新引入的“Imagine Me”功能尤为引人注目。在这一功能下,美国地区的用户只需上…...

常用自启设置
一、开机自启动 1、编辑 vi /lib/systemd/system/nginx.service 文件,没有创建一个 touch nginx.service 然后将如下内容根据具体情况进行修改后,添加到nginx.service文件中: [Unit] Descriptionnginx Afternetwork.target remote-fs.targ…...

模块与组件、模块化与组件化的理解
在React或其他现代JavaScript框架中,模块与组件、模块化与组件化是核心概念,它们对于提高代码的可维护性、复用性和开发效率具有重要意义。以下是对这些概念的理解: 模块与组件 模块(Module) 定义:模块是…...

Rust:cargo的常用命令
1.查看版本 $ cargo --version cargo 1.79.0 (ffa9cf99a 2024-06-03) 2.创建新的项目 $ cargo new hello 创建后的目录结构为 $ tree hello/ hello/ ├── Cargo.toml └── src └── main.rs 3.运行项目 $ cd hello $ cargo run Compiling hello v0.1.0 (/home/c…...

LeetCode 3106.满足距离约束且字典序最小的字符串:模拟(贪心)
【LetMeFly】3106.满足距离约束且字典序最小的字符串:模拟(贪心) 力扣题目链接:https://leetcode.cn/problems/lexicographically-smallest-string-after-operations-with-constraint/ 给你一个字符串 s 和一个整数 k 。 定义函…...

Elasticsearch 与 MySQL 在查询和插入性能上的深度剖析
在当今的数据处理领域,选择合适的数据库对于应用的性能和效率至关重要。Elasticsearch 和 MySQL 作为两款常用的数据库,它们在查询和插入操作上的性能表现各有千秋。本文将对这两款数据库在这两个关键操作上进行详细的对比分析。 一、引言 随着数据量的…...

day4 vue2以及ElementUI
创建vue2项目 可能用到的命令行们 vue create 项目名称 // 创建项目 cd 项目名称 // 只有进入项目下,才能运行 npm run serve // 运行项目 D: //切换盘符 cd .. // 返回到上一级目录 clear // 清空终端 更改 Vue项目的端口配置 基础语法 项目创建完成之后&#…...

把redis用在Java项目
1. Java连接redis Java连接redis的方式是通过jedis,连接redis需要遵循jedis协议。 1.1 引入依赖 <!--引入java连接redis的驱动--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version&…...

GORM:优雅的Go语言ORM库
文章目录 引言GORM原理基础使用安装GORM定义模型连接数据库CRUD操作 高级使用关联事务回调 优点结论 引言 在Go语言开发中,数据库操作是不可或缺的一部分。虽然直接使用SQL语句可以灵活地与数据库交互,但随着项目规模的扩大,SQL语句的编写、…...

Golang | Leetcode Golang题解之第279题完全平方数
题目: 题解: // 判断是否为完全平方数 func isPerfectSquare(x int) bool {y : int(math.Sqrt(float64(x)))return y*y x }// 判断是否能表示为 4^k*(8m7) func checkAnswer4(x int) bool {for x%4 0 {x / 4}return x%8 7 }func numSquares(n int) i…...

Oracle系统表空间的加解密
实验环境 数据库选择的是orclpdb1,当前系统表空间未加密: SQL> show con_nameCON_NAME ------------------------------ ORCLPDB1SQL> select TABLESPACE_NAME, STATUS, ENCRYPTED from dba_tablespaces;TABLESPACE_NAME STATUS …...

pytorch backbone
1 简介 在PyTorch深度学习中,预训练backbone(骨干网络)是一个常见的做法,特别是在处理图像识别、目标检测、图像分割等任务时。预训练backbone通常是指在大型数据集(如ImageNet)上预先训练好的卷积神经网络…...

uniapp 开发app使用renderjs操作dom
需求:把页面中的对话内容另存为一张图片保存到手机相册。 解决方案:这时我们需要使用到document对象创建一个dom对象计算对话内容的宽高、位置等,再利用canvas能力将内容绘制绘制成一张图保存。 现状:总所周知,非H5端&…...

【面试题】MySQL `EXPLAIN`的`Extra`字段:深入解析查询优化的隐藏信息
MySQL EXPLAIN的Extra字段:深入解析查询优化的隐藏信息 引言 在MySQL的EXPLAIN输出中,Extra字段提供了关于查询执行计划的额外信息。这些信息对于理解查询的内部工作机制和优化查询性能至关重要。本文将详细解析Extra字段中常见的几个关键指标…...

Jenkins持续部署
开发环境任务的代码只要有更新,Jenkins会自动获取新的代码并运行 1. pycharm和git本地集成 获取到下面的 Git可执行文件路径 2. pycharm和gitee远程仓库集成 先在pycharm中安装gitee插件 在设置中找到gitee,点击添加账户,并将自己的账户添…...

橙单前端项目下载编译遇到的问题与解决
今天下载orange-admin前端项目,不过下载下来运行也出现一些问题。 1、运行出现下面一堆错误,如下: 2、对于下面这个错误 error Expected linebreaks to be LF but found CRLF linebreak-style 这就是eslint的报错了,可能是原作者…...

在android中怎么处理后端返回列表中包含图片id,如何将列表中的图片id转化成url
在 Android 中实现从包含图片 ID 的列表获取实际图片 URL 并显示图片,你可以使用以下步骤: 定义数据模型:创建一个 Java 或 Kotlin 类来表示列表中的对象。 网络请求:使用 Retrofit 或其他网络库来获取图片 URL。 异步处理:使用 AsyncTask、RxJava 或 Kotlin 协程来处理网…...

IM聊天代码
客户端 Headers inet inet.h #pragma once #include<Winsock2.h>//#pragma comment(lib,"Ws2_32.lib")class INetMediator; class INet { public:INet(){}virtual ~INet(){}//初始化网络virtual bool initNet() 0;//接收数据virtual void recvData() 0;…...

【Go - context 速览,场景与用法】
作用 context字面意思上下文,用于关联管理上下文,具体有如下几个作用 取消信号传递:可以用来传递取消信号,让一个正在执行的函数知道它应该提前终止。超时控制:可以设定一个超时时间,自动取消超过执行时间…...