先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注go)
正文
1.打印菜单
2.接收变量
3.打印雷区
4.接收坐标
5.判断雷区周围包括坐标本身在内的 9个坐标内有几个雷
6. *为显示可排查区域
7. 1为雷
8.踩到雷结束游戏
9.全部排查则游戏胜利
************************
******* 1.play *******
******* 0.exly *******
************************
请选择输入开始游戏:> 1
共有30个雷
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
//作弊 看到雷的布局
0 1 2 3 4 5 6 7 8 9
1 0 0 1 1 1 0 0 1 0
2 1 0 0 1 1 0 0 0 1
3 0 0 0 1 1 0 0 1 0
4 1 1 0 1 1 0 0 0 0
5 0 0 1 1 0 1 1 1 1
6 0 0 0 1 0 0 0 0 0
7 1 1 0 1 0 0 1 0 0
8 0 0 0 0 0 0 0 0 0
9 0 0 1 1 1 0 0 0 1
请输入坐标:5 5
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * 5 * * * * 显示周围雷的数量
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
游戏分为——两部分
- 开始游戏
- 结束游戏
开始游戏分为——四部分
- 创建雷区
- 初始化并打印
- 生成雷
- 排查雷
简单看一下整体布局 不至于从一开始就劝退初学者
全文共217行代码 整体代码在文章最后
下面跟随我的思路一起完成扫雷游戏吧!
首先创建三个文件
.c 文件是C语言文件
.h 文件是头文件
- test.c :写主程序的.c文件
- game.c : 写游戏主要代码的.c文件
- game.h :引用 头文件 和 声明的.h头文件
在test.c文件中
创建main函数主体
主要思路是:
如在手机中观看 可左右滑动查看查处部分代码
void emnu()
{
printf(“************************\n”);
printf(“******* 1.play *******\n”);
printf(“******* 0.exly *******\n”);
printf(“************************\n”);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //后面创建随机数的函数
do {
//打印菜单
emnu();
printf(“请选择输入开始游戏:> “);
scanf(”%d”, &input);
switch (input)
{
case 1:
game();
//printf(“游戏开始\n”);
break;
case 0:
printf(“游戏结束\n”);
break;
default:
printf(“输入错误,请重新选择!\n”);
break;
}
} while (input);
return 0;
}
srand((unsigned int)time(NULL)); 对于这句话后面会讲到
1.打印菜单
2.接收字符
3.判断状态
为了一打开程序就进入游戏状态
所以用了 do{}while{} 循环
1.打印菜单调用 emnu()函数
void emnu()
{
printf(“************************\n”);
printf(“******* 1.play *******\n”);
printf(“******* 0.exly *******\n”);
printf(“************************\n”);
}
2.接收字符
我们在循环外部定义
int input = 0; 接收指令的变量
scanf(“%d”,&input); 接收键盘输入的函数
注意:
%d后面不要加空格
& 符号不要忘记写
3.判断接收字符的状态
switch(整形表达式)
{
case 整形常量表达式:
break; //跳出switch 去下面的while中判断是否继续循环
case 0:
break;
default://相当于if语句中的else的作用
//当上面的语句都不满足时 执行此语句
break;
}while(input); //input为0时结束游戏
输入1 继续游戏
输入0 结束游戏
输入错误 给出提示并从新输入
- 可以在game.h中引入头文件
- 并且在test.c中引入game.h头文件
- 这样所有头文件都放在game.h中就可以了game.h
#pragma once
#include <stdio.h>
在头文件中 第一行 写入#pragma once
在其他文件中不管包含几次<stdio.h>都只拷贝一次
是为了防止头文件重复 做无用功
test.c
#include “game.h”
经过上面的代码 可以在case 1: 中调用函数game()
ganme()分为——五部分
- 1.创建雷区
- 2.初始化
- 3.打印初始化
- 4.生成雷
- 5.排查雷
1.创建雷区
test.c
void game()
{
char LQu[ROWS][COLS]; 存放雷的信息
char PCha[ROWS][COLS]; 排查雷的信息
}
so easy 有没有 雷区创建好了
2.初始化雷区
void game()
{
//创建雷区
char LQu[ROWS][COLS]; //存放雷的信息
char PCha[ROWS][COLS];//排查雷的信息
//初始化
CShi(LQu, ROWS, COLS,‘0’);//雷区
CShi(PCha,ROWS, COLS,‘*’);//排查区
//打印初始化
//DY(LQu, ROW, COL);//雷区
printf(“共有%d个雷\n”,LEI);
DY(PCha, ROW, COL);//排查区
//生成雷
S_L(LQu, ROW, COL,LEI);
printf(“\n”);
//DY(LQu, ROW, COL);//雷区
//排查雷
P_C(LQu,PCha, ROW, COL);
DY(PCha, ROW, COL);//排查区
}
可以看到创建雷区 用到了两个数组 LQu PCha
先看下game.h中的代码
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2 //ROW+2
#define COLS COL+2 //COL+2
#define LEI 10
//初始化
void CShi(char CShi[ROWS][COLS], int rows, int cols,char ret);//雷区
上述数组用到了两个 常量ROWS、COLS 怎么来的?
这里用到5个变量,用#define定义
#define 定义全局变量
ROW 为用户可见区域 横坐标
COL 为用户可见区域 纵坐标
ROWS 为底层排雷区域 横坐标
COLS 为底层排雷区域 纵坐标
LEI 为雷的个数
为什么分为 ROW 和 ROWS 呢
我们开头说到 比如是9*9 的格子
在扫描雷的时候要扫描坐标在内的周围的9个格子
如下:
* * *
* n *
* * *
整体的布局:(ROW,COL)
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
但是:
左上(1,1),左下(1,9),右上(9,1),右下(9,9)…
这几个坐标访问时就越界了
所以:
我们在底层代码扫描时 把上下左右都加上一行
这时访问数组时就不会出现越界了
也就有了ROWS、COLS 这两个变量
#define ROW 9
#define COL 9
#define ROWS ROW+2 //ROW+2
#define COLS COL+2 //COL+2
game.h 中下方还有一行代码——初始化 (下)
左右滑动查看代码
test.c
char LQu[ROWS][COLS]; //存放雷的信息 定义数组
char PCha[ROWS][COLS];//排查雷的信息 定义数组
//需要初始化的代码:
CShi(LQu, ROWS, COLS,‘0’);//雷区
CShi(PCha,ROWS, COLS,‘*’);//排查区
这样设计用一个函数传参 就能给不同数组 初始化成不同的 字符
game.h
//初始化
void CShi(char CShi[ROWS][COLS], int rows, int cols,char ret);//雷区
函数返回类型 不需要返回值 所以为 void
数组传参 接收一个数组 用char CShi[][]数组接收
ROWS COLS 是整形 用int 类型变量接收
后面的 ‘0’ ‘*’ 用char 字符类型接收
因为排查雷需要更大的数组 所以用到了 ROWS COLS
test.c 中定义函数
game.h 声明函数
game.c 实现代码
game.c
#include “game.h”
//初始化雷区
void CShi (char CShi[ROWS][COLS], int rows, int cols,char ret)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
CShi[i][j] = ret;
}
}
}
用for循环将两个数组初始化成全0 全*
CShi(LQu, ROWS, COLS,‘0’);
0 1 2 3 4 5 6 7 8 9 a b
1 0 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0 0 0 0
a 0 0 0 0 0 0 0 0 0 0 0
b 0 0 0 0 0 0 0 0 0 0 0
这一层布置雷 扫雷
CShi(PCha,ROWS, COLS,‘*’);
0 1 2 3 4 5 6 7 8 9 a b
1 * * * * * * * * * * *
2 * * * * * * * * * * *
3 * * * * * * * * * * *
4 * * * * * * * * * * *
5 * * * * * * * * * * *
6 * * * * * * * * * * *
7 * * * * * * * * * * *
8 * * * * * * * * * * *
9 * * * * * * * * * * *
a * * * * * * * * * * *
b * * * * * * * * * * *
这一层打印出来给用户看 当然不是打印11*11 是打印9*9 后面会说到
(16进制 a=10 b=11 c=12 d=13 e=14 f=15)
3.打印初始化
test.c
//打印初始化
DY(PCha, ROW, COL);//排查区
printf(“共有%d个雷\n”,LEI); //告诉用户有几个雷
game.h
//打印初始化
void DY(char LQu[ROWS][COLS],int rows,int cols);//雷区
传参上面讲了 同理
这里要强调的是传参的时候用的是ROW COL
因为打印出来的是要给用户观察的
ROW COL 定义的为9
所以要打印9*9 的个格子
聪明的你要问了:怎么才能在11*11 的数组中打印9*9 的格子呢?
你: 我才没问呢 我都知道!
你: 只要在数组下标为1 的地方打印到下标10就可以啦
你真是个机灵鬼!!!
game.c
//打印
void DY(char LQu[ROWS][COLS], int row, int col)
{
int i = 0;
for (i = 0; i <= row; i++)
{
printf(“%d “, i);
}
printf(”\n”);
for (i = 1; i <= row; i++)
{
int j = 0;
printf(“%d “, i);
for (j = 1; j <= col; j++)
{
printf(”%c “, LQu[i][j]);
}
printf(”\n”);
}
printf(“\n”);
}
上述代码 第一个循环 是打印出了每行的编号 为了方便观察
下面的代码 也在每一行的首元素打印了编号
最后for循环打印的数组初始化的内容
打印结果如下:DY(PCha, ROW, COL);
共有10个雷
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
4.生成雷
test.c
//生成雷
S_L(LQu, ROW, COL,LEI);
printf(“\n”);
game.h
//生成雷
void S_L(char LQu[ROWS][COLS], int row, int col,int lei);
game.c
//生成雷
void S_L(char LQu[ROWS][COLS], int row, int col,int lei)
{
int i = lei;
while(i)
{
int x = rand() % row+1;
int y = rand() % col+1;
if (LQu[x][y] != ‘1’)
{
LQu[x][y] = ‘1’;
i–;
}
}
}
思路:
1.x y在规定坐标内 生成随机数
一个随机数%10 则得到的结果不会大于10 也就是最大得到9
2.在随机产生的坐标中放入字符’1’
产生随机数rand()
在主函数中调用srand()
srand((unsigned int)time(NULL));
接收time系统时间 强制准换成无符号整型(unsigned int)
srand() 的头文件 <stdlib.h>
time() 的头文件 <time.h>
此时就可以在已经声明的范围内 使用rand()
还差一步就完成啦 ٩(๑>◡<๑)۶ 加油!
5.排查雷
败北:坐标 = ‘1’
胜利:输入坐标 = 坐标 - 雷
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
le(i)
{
int x = rand() % row+1;
int y = rand() % col+1;
if (LQu[x][y] != ‘1’)
{
LQu[x][y] = ‘1’;
i–;
}
}
}
思路:
1.x y在规定坐标内 生成随机数
一个随机数%10 则得到的结果不会大于10 也就是最大得到9
2.在随机产生的坐标中放入字符’1’
产生随机数rand()
在主函数中调用srand()
srand((unsigned int)time(NULL));
接收time系统时间 强制准换成无符号整型(unsigned int)
srand() 的头文件 <stdlib.h>
time() 的头文件 <time.h>
此时就可以在已经声明的范围内 使用rand()
还差一步就完成啦 ٩(๑>◡<๑)۶ 加油!
5.排查雷
败北:坐标 = ‘1’
胜利:输入坐标 = 坐标 - 雷
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-aSxIqMY4-1713174585420)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!