扫雷小游戏

描述

    用C语言实现扫雷小游戏。

要求

    1、第一步不能被炸死。

    2、输入一个坐标,可以展开一片。

思路

    先给出一个头文件game.c,是我们自定义的一个头文件,里面有我们在写扫雷程序里面所需要的所有头文件、常量还有所有函数的声明。

game.h

#define _CRT_SECURE_NO_WARNINGS 1

#ifndef __GAME_H__
#define __GAME_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define ROW 9
#define COL 9
#define ROWS (ROW+2)
#define COLS (COL+2)
#define EASY_MODE 10


int book[ROWS][COLS];

void DisplayBoard(char board[ROWS][COLS], int row, int col);
void Init(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void setMine(char mine[ROWS][COLS], int row, int col);
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int GetCount(char mine[ROWS][COLS], int x, int y);
void SafeMove(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int CountShow(char show[ROWS][COLS], int row, int col);

#endif //__GAME_H__

接下来就是我整个程序的设计思路!!!!

    1、首先最重要的是先写主函数(main()),然后根据主函数的需要来设计自定义函数。

int main(void)
{
	int i = 0;
	int j = 0;
	int input = 0;

	srand((unsigned int)time(NULL));

	//调用菜单函数,打印游戏菜单
	menu();

	do
	{
		printf("请输入您要选的选项:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏!\n");
				break;
			default:
				printf("输入错误!请重新输入!\n");
				break;
		}

	} while (input);

	system("pause");
	return 0;
}

    因为这个游戏不能只玩一次就退出了,选择权在玩家手里,所以我们需要一个循环来判断玩家还想不想玩。

    2、然后根据主函数的需要,我们先写一个菜单函数,这个函数很简单,只需要输出就好,菜单的样子也是根据你的喜好来设计。

void menu()
{
	printf("***********************************\n");
	printf("*******        1. play      *******\n");
	printf("*******        0. exit      *******\n");
	printf("***********************************\n");
}

    3、接下来我们需要game()函数啦,在这个函数里我们将要实现扫雷游戏的全部内容,也是一样,我们在这个函数里先写一个大的框架,需要什么函数我们先写下名字,然后再根据我们的需要去在game.c里设计所有我们需要的自定义函数。首先需要两个数组,分别为mine[][] 和 show[][] 用来记录扫雷盘,mine数组用来存哪里是地雷,哪里不是地雷。show数组用来给玩家显示玩游戏的过程。

    扫雷的面板是9X9,但是我们要给数组11X11,因为在算某个坐标的周围有多少个地雷的时候我们需要扫描他周围8个格子,目前我的水平,还做不到让它根据实际情况去扫描,所以我给二维数组多定义一圈,让它们初始化跟内圈一样为‘0’,这样扫描的时候就不算那些格子了。所以,我们需要初始化函数,还有打印的函数,不打印怎么玩!!!!!

    其次,我们要一个函数来随机摆放地雷的位置,那么就有了setMine函数。这里说一下,因为随机所以需要rand()库函数,但是调用rand之前,要在main里面写一句

	srand((unsigned int)time(NULL));

    要不然rand的随机值每次开始都一样。

    因为第一步不能炸死,我们就需要设计SaveMove函数,第一步走完,要判断一下玩家赢了没有,说不定就一个地雷呢!随便走一步,多数情况就赢了!所以需要一个CountShow函数来算现在show数组里还有多少个‘*’,如果‘*’跟地雷的数目一样,那么玩家就赢了呀!

    如果第一步没有赢,那就往下走,因为往往需要多次才能赢,我们就设计一个循环实现,先来个死循环while(1),赢了或者输了跳出去就行了嘛!

    再来一个FindMine函数,来判断玩家踩到地雷了没有,踩到了就返回1,没踩到就返回0 。

    如果 没踩到就继续判断一个赢了没有呀!

    那么如果没有赢也没有输,那就再打印一遍show 数组,让玩家继续玩下去,当然是修改后的show数组!

void game()
{
	int is = 0;

	//mine 数组存储雷的位置 0 为空,1 为雷
	char mine[ROWS][COLS] = { 0 };
	//show 数组存储游戏盘,并且在每次点击后显示周围雷的个数
	char show[ROWS][COLS] = { 0 };
	
	//初始化mine 数组所有元素为'0',show 数组所有元素为'*'
	Init(mine, show, ROWS, COLS);
	
	//设置地雷
	setMine(mine, ROWS, COLS);

	//打印mine 数组
	DisplayBoard(mine, ROWS, COLS);

	printf("\n");
	printf("-------------------------\n");
	printf("\n");

	//打印游戏面板
	DisplayBoard(show, ROWS, COLS);
	//第一步不被炸死
	SafeMove(mine, show, ROWS, COLS);

	//如果面板上剩下的'*' 与地雷的总数相同时,玩家赢
	if (CountShow(show, ROWS, COLS) == EASY_MODE)
	{
		printf("-------------------------\n");
		DisplayBoard(mine, ROWS, COLS);
		printf("恭喜你!你赢了!\n");
		return;
	}
	
	/*DisplayBoard(mine, ROWS, COLS);
	printf("\n");
	printf("-------------------------\n");
	printf("\n");*/
	DisplayBoard(show, ROWS, COLS);
	

	while (1)
	{
		//判断玩家选择的坐标是不是地雷,若是则返回1,若不是则展开附近地雷信息
		is = FindMine(mine, show, ROWS, COLS);
		//如果面板上剩下的'*' 与地雷的总数相同时,玩家赢
		if (CountShow(show, ROWS, COLS) == EASY_MODE)
		{
			printf("-------------------------\n");
			DisplayBoard(mine, ROWS, COLS);
			printf("恭喜你!你赢了!\n");
			break;
		}
		
		if (is == 1)
		{
			printf("BOOM!!!!!!!!!!\n");
			printf("很遗憾,你被炸死了!\n");
			DisplayBoard(mine, ROWS, COLS);
			break;
		}

	/*	DisplayBoard(mine, ROWS, COLS);
		printf("\n");
		printf("-------------------------\n");
		printf("\n");*/
		DisplayBoard(show, ROWS, COLS);

	}
}

    在注释掉的显示mine数组的部分,是调试的时候我们需要知道地雷在哪里,我们才能实现我们想要的结果,当然,如果你聪明绝顶,那就当我刚才放了个屁。

    4、接下来我们要开始写game()函数里面所需要的函数了,就像刚才所说的,最基本的就是初始化和打印函数了,这个没有什么难的,不过初始化函数里用到了memset()库函数,这个函数参数依次是,(需要修改的内存起始地址, 需要修改为的字符 , 字符的个数是多少)

void Init(char board[ROWS][COLS],   int row, int col, char ch)
{
	memset(&board[0][0], ch, row*col*sizeof(board[0][0]));
}

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	//打印横坐标
	printf("0 ");
	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
		
		for (j = 1; j < col - 1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
		
	}
}

    5、下来就是设置地雷的函数。需要注意的点已经在第3点里面提到了!

void setMine(char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = EASY_MODE;


	while (count)
	{
		//我们需要9个数字,如果%10产生的是0~8, 9个数字
		//但是我们需要1~9,所以先%9产生8个数字,再加1就好
		x = rand() % 9 + 1;
		y = rand() % 9 + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

    6、下来就是第一步不能被炸死这个函数SaveMove。

 

void SafeMove(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int flag = 1;
	int count = 0;
	char ch = 0;

	while (1)
	{
		printf("请输入您要选择的坐标:");
		scanf("%d%d", &x, &y);

		if (x < 1 && x > COL && y < 1 && y > ROW)
		{
			printf("您输入的坐标超过当前地图,请重新输入!\n");
			continue;
		}

		if (mine[x][y] == '1')
		{
			//如果玩家输入的坐标是1,则强行把这个坐标改为0
			mine[x][y] = '0';
			char ch = GetCount(mine, x, y);
			show[x][y] = ch + '0';
			book[x][y] = 1;
			open(mine, show, x, y);
			//将一个地雷改为了空地,则需要再随机填一个雷
			while (flag)
			{
				x = rand() % 9 + 1;
				y = rand() % 9 + 1;
				if (mine[x][y] == '0')
				{
					mine[x][y] = '1';
					flag--;
					break;
				}
			}break;
		}
		else if (mine[x][y] == '0')
		{
			char ch = GetCount(mine, x, y);
			show[x][y] = ch + '0';
			book[x][y] = 1;
			open(mine, show, x, y);
			break;
		}

	}

}

7、第一步走完,需要判断一下玩家赢了没有,说不定就是那么腻害!怎么判断赢了没有呀!往前翻!!!不认真看!

    所以需要一个CountShow函数来算现在show数组里还有多少个‘*’,如果‘*’跟地雷的数目一样,那么玩家就赢了呀!

int CountShow(char show[ROWS][COLS], int row, int col)//判断剩余未知区域的个数,个数为雷数时玩家赢
{
	int count = 0;
	int i = 0;
	int j = 0;
	for (i = 1; i < row - 1; i++)
	{
		for (j = 1; j < col - 1; j++)
		{
			if (show[i][j] == '*')
			{
				count++;
			}
		}

	}
	return count;
}

8、第一步走完了,那么就要走下一步了,我们就有了FindMine函数,用来判断玩家走的是不是地雷所在的位置。

//踩到雷返回1,没有踩到雷返回0
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;

	
	printf("请输入您选择的坐标:");
	scanf("%d%d", &x, &y);

	if (x < 1 && x > COL && y < 1 && y > ROW)
	{
		printf("您输入的坐标超过当前地图,请重新输入!\n");
			
	}
	else
	{
		if (mine[x][y] == '0')
		{
			char ch = GetCount(mine, x, y);
			show[x][y] = ch + '0';
			book[x][y] = 1;
			open(mine, show, x, y);
			if (CountShow(show, row, col) == EASY_MODE)
			{
				return 0;
			}
		}
		else if (mine[x][y] == '1')
		{
			return 1;
		}

	}
	return 0;
}

    9、接下来,最重要的一步!!!!!!!!

    如果我们选择一个坐标,那个坐标不是地雷,我们就要像别人家的扫雷一样,去展开一片没有雷的区域。那么这个区域什么时候是个头呢,那就是要被提示附近有地雷的数字包围起来!

    这个函数用到了深度优先算法,里面有递归所以要好好看。

    注意:next数组用来存放一组上下左右移动的方向。

               tx和ty用来存放下一步的坐标

    而且这个函数里用到了算周围有几个地雷的函数,GetCount函数一并附在下面!

//用深度优先搜索来对面板展开
void open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	
	int tx = 0;
	int ty = 0;
	int k = 0;
	//定义next数组,用来对四个方向进行搜索
	int next[4][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };

	//在展开的时候如果GetCount函数返回的不是0,则给show数组赋返回的值
	if (GetCount(mine, x, y) != 0)
	{
		show[x][y] = GetCount(mine, x, y) + '0';
	}
	//如果是0,给show数组那个位置赋空格
	else if (GetCount(mine, x, y) == 0)
	{
		show[x][y] = ' ';
	}
	
	for (k = 0; k <= 3; k++)
	{
		tx = x + next[k][0];
		ty = y + next[k][1];

		if (tx < 1 || tx > ROW || ty < 1 || ty > COL)
		{
			continue;
		}
		if (mine[tx][ty] == '0' && book[tx][ty] == 0 && GetCount(mine, tx, ty) < 1)
		{
			
			book[tx][ty] = 1;
			open(mine, show, tx, ty);
		
		}
		//这一步很关键,是展开时遇到数字停下来的一步
		if (mine[tx][ty] == '0' && book[tx][ty] == 0 && GetCount(mine, tx, ty) > 0)
		{
			show[tx][ty] = GetCount(mine, tx, ty) + '0';
			continue;
		}
		
	}
	return;
}

//统计面板上剩下的'*'
int CountShow(char show[ROWS][COLS], int row, int col)//判断剩余未知区域的个数,个数为雷数时玩家赢
{
	int count = 0;
	int i = 0;
	int j = 0;
	for (i = 1; i < row - 1; i++)
	{
		for (j = 1; j < col - 1; j++)
		{
			if (show[i][j] == '*')
			{
				count++;
			}
		}

	}
	return count;
}
int GetCount(char mine[ROWS][COLS], int x, int y)
{
	int count = 0;
	//分别对(x,y)坐标周围8个格子进行判断,如果是雷则count + 1
	//最后返回count就是(x,y)周围的地雷个数
	if (mine[x - 1][y] == '1')
		count++;
	if (mine[x - 1][y - 1] == '1')
		count++;
	if (mine[x][y - 1] == '1')
		count++;
	if (mine[x + 1][y - 1] == '1')
		count++;
	if (mine[x + 1][y] == '1')
		count++;
	if (mine[x + 1][y + 1] == '1')
		count++;
	if (mine[x][y + 1] == '1')
		count++;
	if (mine[x - 1][y + 1] == '1')
		count++;

	return count;
}

源代码

game.h

#define _CRT_SECURE_NO_WARNINGS 1

#ifndef __GAME_H__
#define __GAME_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define ROW 9
#define COL 9
#define ROWS (ROW+2)
#define COLS (COL+2)
#define EASY_MODE 10


int book[ROWS][COLS];

void DisplayBoard(char board[ROWS][COLS], int row, int col);
void Init(char board[ROWS][COLS],  int row, int col, char ch);
void setMine(char mine[ROWS][COLS], int row, int col);
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int GetCount(char mine[ROWS][COLS], int x, int y);
void SafeMove(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int CountShow(char show[ROWS][COLS], int row, int col);

#endif //__GAME_H_

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

/*
* 实现扫雷游戏的测试
* 要求:
* 1、第一步不能炸死
* 2、点开一个若不是雷,则可以展开一片
* 郭文峰
* 2018/10/19
*/

void menu()
{
	printf("***********************************\n");
	printf("*******        1. play      *******\n");
	printf("*******        0. exit      *******\n");
	printf("***********************************\n");
}

void game()
{
	int is = 0;

	//mine 数组存储雷的位置 0 为空,1 为雷
	char mine[ROWS][COLS] = { 0 };
	//show 数组存储游戏盘,并且在每次点击后显示周围雷的个数
	char show[ROWS][COLS] = { 0 };
	
	//初始化mine 数组所有元素为'0',show 数组所有元素为'*'
	//Init(mine, show, ROWS, COLS);
	Init(mine, ROWS, COLS, '0');
	Init(show, ROWS, COLS, '*');

	//设置地雷
	setMine(mine, ROWS, COLS);

	//打印mine 数组
	DisplayBoard(mine, ROWS, COLS);

	printf("\n");
	printf("-------------------------\n");
	printf("\n");

	//打印游戏面板
	DisplayBoard(show, ROWS, COLS);
	//第一步不被炸死
	SafeMove(mine, show, ROWS, COLS);

	//如果面板上剩下的'*' 与地雷的总数相同时,玩家赢
	if (CountShow(show, ROWS, COLS) == EASY_MODE)
	{
		printf("-------------------------\n");
		DisplayBoard(mine, ROWS, COLS);
		printf("恭喜你!你赢了!\n");
		return;
	}
	
	/*DisplayBoard(mine, ROWS, COLS);
	printf("\n");
	printf("-------------------------\n");
	printf("\n");*/
	DisplayBoard(show, ROWS, COLS);
	

	while (1)
	{
		//判断玩家选择的坐标是不是地雷,若是则返回1,若不是则展开附近地雷信息
		is = FindMine(mine, show, ROWS, COLS);
		//如果面板上剩下的'*' 与地雷的总数相同时,玩家赢
		if (CountShow(show, ROWS, COLS) == EASY_MODE)
		{
			printf("-------------------------\n");
			DisplayBoard(mine, ROWS, COLS);
			printf("恭喜你!你赢了!\n");
			break;
		}
		
		if (is == 1)
		{
			printf("BOOM!!!!!!!!!!\n");
			printf("很遗憾,你被炸死了!\n");
			DisplayBoard(mine, ROWS, COLS);
			break;
		}

	/*	DisplayBoard(mine, ROWS, COLS);
		printf("\n");
		printf("-------------------------\n");
		printf("\n");*/
		DisplayBoard(show, ROWS, COLS);

	}
}


int main(void)
{
	int i = 0;
	int j = 0;
	int input = 0;

	srand((unsigned int)time(NULL));

	//调用菜单函数,打印游戏菜单
	menu();

	do
	{
		printf("请输入您要选的选项:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏!\n");
				break;
			default:
				printf("输入错误!请重新输入!\n");
				break;
		}

	} while (input);

	system("pause");
	return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void Init(char board[ROWS][COLS],   int row, int col, char ch)
{
	memset(&board[0][0], ch, row*col*sizeof(board[0][0]));
}

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	//打印横坐标
	printf("0 ");
	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
		
		for (j = 1; j < col - 1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
		
	}
}

void setMine(char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = EASY_MODE;


	while (count)
	{
		//我们需要9个数字,如果%10产生的是0~8, 9个数字
		//但是我们需要1~9,所以先%9产生8个数字,再加1就好
		x = rand() % 9 + 1;
		y = rand() % 9 + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

//踩到雷返回1,没有踩到雷返回0
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;

	
	printf("请输入您选择的坐标:");
	scanf("%d%d", &x, &y);

	if (x < 1 && x > COL && y < 1 && y > ROW)
	{
		printf("您输入的坐标超过当前地图,请重新输入!\n");
			
	}
	else
	{
		if (mine[x][y] == '0')
		{
			char ch = GetCount(mine, x, y);
			show[x][y] = ch + '0';
			book[x][y] = 1;
			open(mine, show, x, y);
			if (CountShow(show, row, col) == EASY_MODE)
			{
				return 0;
			}
		}
		else if (mine[x][y] == '1')
		{
			return 1;
		}

	}
	return 0;
}

int GetCount(char mine[ROWS][COLS], int x, int y)
{
	int count = 0;
	//分别对(x,y)坐标周围8个格子进行判断,如果是雷则count + 1
	//最后返回count就是(x,y)周围的地雷个数
	if (mine[x - 1][y] == '1')
		count++;
	if (mine[x - 1][y - 1] == '1')
		count++;
	if (mine[x][y - 1] == '1')
		count++;
	if (mine[x + 1][y - 1] == '1')
		count++;
	if (mine[x + 1][y] == '1')
		count++;
	if (mine[x + 1][y + 1] == '1')
		count++;
	if (mine[x][y + 1] == '1')
		count++;
	if (mine[x - 1][y + 1] == '1')
		count++;

	return count;
}

//SafeMove函数是保证玩家输入第一个坐标时不被炸死
void SafeMove(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int flag = 1;
	int count = 0;
	char ch = 0;

	while (1)
	{
		printf("请输入您要选择的坐标:");
		scanf("%d%d", &x, &y);

		if (x < 1 && x > COL && y < 1 && y > ROW)
		{
			printf("您输入的坐标超过当前地图,请重新输入!\n");
			continue;
		}

		if (mine[x][y] == '1')
		{
			//如果玩家输入的坐标是1,则强行把这个坐标改为0
			mine[x][y] = '0';
			char ch = GetCount(mine, x, y);
			show[x][y] = ch + '0';
			book[x][y] = 1;
			open(mine, show, x, y);
			//将一个地雷改为了空地,则需要再随机填一个雷
			while (flag)
			{
				x = rand() % 9 + 1;
				y = rand() % 9 + 1;
				if (mine[x][y] == '0')
				{
					mine[x][y] = '1';
					flag--;
					break;
				}
			}break;
		}
		else if (mine[x][y] == '0')
		{
			char ch = GetCount(mine, x, y);
			show[x][y] = ch + '0';
			book[x][y] = 1;
			open(mine, show, x, y);
			break;
		}

	}

}

//用深度优先搜索来对面板展开
void open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	
	int tx = 0;
	int ty = 0;
	int k = 0;
	//定义next数组,用来对四个方向进行搜索
	int next[4][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };

	//在展开的时候如果GetCount函数返回的不是0,则给show数组赋返回的值
	if (GetCount(mine, x, y) != 0)
	{
		show[x][y] = GetCount(mine, x, y) + '0';
	}
	//如果是0,给show数组那个位置赋空格
	else if (GetCount(mine, x, y) == 0)
	{
		show[x][y] = ' ';
	}
	
	for (k = 0; k <= 3; k++)
	{
		tx = x + next[k][0];
		ty = y + next[k][1];

		if (tx < 1 || tx > ROW || ty < 1 || ty > COL)
		{
			continue;
		}
		if (mine[tx][ty] == '0' && book[tx][ty] == 0 && GetCount(mine, tx, ty) < 1)
		{
			
			book[tx][ty] = 1;
			open(mine, show, tx, ty);
		
		}
		//这一步很关键,是展开时遇到数字停下来的一步
		if (mine[tx][ty] == '0' && book[tx][ty] == 0 && GetCount(mine, tx, ty) > 0)
		{
			show[tx][ty] = GetCount(mine, tx, ty) + '0';
			continue;
		}
		
	}
	return;
}

//统计面板上剩下的'*'
int CountShow(char show[ROWS][COLS], int row, int col)//判断剩余未知区域的个数,个数为雷数时玩家赢
{
	int count = 0;
	int i = 0;
	int j = 0;
	for (i = 1; i < row - 1; i++)
	{
		for (j = 1; j < col - 1; j++)
		{
			if (show[i][j] == '*')
			{
				count++;
			}
		}

	}
	return count;
}

总结:

    这个程序难的地方就是你要有一个清晰的思路,知道你需要干什么,所以这里我是先写大的框架,然后我需要用到什么,我再去写什么,一点一点的去完成。

    还有写程序的时候遇到难题就是再展开这一块,还好之前看的算法书起了作用,这里安利一本叫《啊哈!算法》的书,里面很可爱的讲了各种算法,推荐新手去看,绝对能看懂!

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值