框架
首先,游戏会有菜单,用来问你是否玩游戏
然后进行选择,根据选择来判断,是玩还是退出
这就不能不让人想到c语言新手必做的猜数字游戏⬇️
我有专题讲过,如果你有兴趣可以看一看,我再简单介绍一下里面的内容,
1.随机数的生成需要rand函数,然后在int main开头加一个srand((unsigned int)time(NULL));,而且需要包含头文件#include <time.h>和#include<stdlib.h>
2.菜单的选择需要用到switch
3.游戏的主体在game()中
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
printf("--------------\n");
printf("----1. play---\n");
printf("----0. leave--\n");
printf("--------------\n");
}
void game()
{
int a = 0;
int r = rand() % 100 + 1;
while(1)
{
printf("请猜数字>:");
scanf("%d", &a);
if(a < r)
printf("猜小了\n");
else if(a > r)
printf("猜大了\n");
else
{printf("恭喜你,猜对了\n");
break;}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{ menu();
printf("请选择>\n");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}while(input);
return 0;
}
其中的框架是我们可以借用的,把框架稍微修改一下,如下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
printf("------扫雷-----\n");
printf("--------------\n");
printf("----1. play---\n");
printf("----0. leave--\n");
printf("--------------\n");
}
void game()
{
???????
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{ menu();
printf("请选择>\n");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}while(input);
return 0;
}
这里需要我们做出改变的地方只有game函数里面的具体内容
游戏主要内容
- 生成两个初始棋盘,一个全都是0,一个全都是星号*
- 在全都是0的棋盘(mine棋盘)中放置10个1表示10个炸弹
- 给你展示全都是星号*的show棋盘,让你选择
- 你通过输入坐标进行选择。选到雷就被炸死。如果没选到雷,就是选到0,这时候星号*变成扫雷游戏中的数字,数字代表附近这一圈中有几个雷
让咱们从头开始说吧
头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
菜单
void menu()
{
printf("------扫雷-----\n");
printf("--------------\n");
printf("----1. play---\n");
printf("----0. leave--\n");
printf("--------------\n");
}
主界面(main函数)
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{ menu();
printf("请选择>\n");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}while(input);
return 0;
}
主要内容与函数
对常用数字赋值
棋盘大小是9*9,我们为了使排查周围雷的时候不会出错,应该在上下两边加上2排格子,然后生成的就是11*11大小的格子
为了以后方便修改棋盘的大小、炸弹的个数,以便生成更难的游戏,最好在开头赋几个值
他们分别是:
显示出的棋盘的行列:row,col
需要不出错的真实棋盘的行和列:rows,cols
炸弹的个数:numofboom
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define numofboom 10
初始化棋盘
- 生成一个函数执行下列任务 , 并且在game函数里面使用
- 生成11*11的数组
- 给每个数组赋值
- 在不展示的雷棋盘中先放上0,
- 在展示给游戏者的show棋盘中放上星号*
//开始给棋盘赋值
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;
}
}
}
void game()
{
char mine[ROWS][COLS]= {0};
char show[ROWS][COLS]= {0};
InitBoard(mine ,ROWS,COLS,'0');
InitBoard(show ,ROWS,COLS,'*');
}
随机放置雷
- 产生函数执行下面的操作,并在game函数中使用
- 生成随机值x,y, 并且这个x,y不能在我们想显示坐标的位置➡️rand
- 让坐标(x,y)处的数字变成雷,也就是变成1➡️数组的赋值
- 一直生成10个这样的雷
//布置雷
void SetMine(char board[ROWS][COLS],int row,int col)
{
int count = numofboom;
while(count)
{
int x = rand() % row +1;
int y = rand() % col +1;
if (board[x][y] =='0')
{
board[x][y]= '1';
}
count --;
}
}
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);
}
展示棋盘
生成打印棋盘的函数完成下列操作,并在game函数中运行
- 开头打印扫雷标签,末尾打印横线
- 在棋盘周围打印坐标行和列
- 在第一行打印列⬅️这个放在开头很方便
- 在后面每一行的开头打印这一行的行数‘
- 打印棋盘‼️注意:只打印原棋盘11*11的中间位置的9*9部分
//展示棋盘
void DisplayBoard(char board[ROWS][COLS], int row ,int col)
{
int i = 0;
int j = 0;
printf("-----扫雷-----\n");
for (i = 0; i<= row;i++)
{
printf("%d ",i);
}
printf("\n");
for(i= 1;i <= row;i++)
{
printf("%d ",i);
for (j = 1 ;j<= col;j++)
{
printf("%c ",board[i][j]);
}
printf("\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);
}
有关字符打印的重要知识
在进行游戏之前,我们先清楚一个概念
打印单个字符用的是%c,可以直接用ASCII码值代替,结果一样,如下
#include <stdio.h>
int main()
{
printf("%c\n", 'Q');
printf("%c\n", 81);
return 0;
}
在进行游戏之前,我们先产生一个
判断周围有几个炸弹
//对周围雷的排查
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
return mine[x+1][y] + mine[x-1][y]+ mine[x][y-1]+ mine[x][y+1] + mine[x-1][y-1] + mine[x-1][y+1] + mine[x+1][y+1] + mine[x+1][y-1]- 8*'0';
}
后面减去8*‘0’的原因是,为了显示具体有几个雷
结合下面的排查雷的这两行代码
int c = GetMineCount(mine, x,y);
show[x][y]=c+'0';
你就能知道,我们得到的c就是具体的几个雷这个数字
可是我们创建的棋盘是char类型的二维数组,
你如果想放进去一个数字0,就得输入48
想放进去字母Q,就得输入81
所以第2行代码show[x][y]=c+'0';
意思就是输入c + 48进去,从而得到c
排查雷
大前提:还存在能够选择的位置
win代表选择正确的次数,numofboom代表炸弹的个数
即 while(win < row *col - numofboom)
- 输入坐标
- 判断坐标是否正确
- 错误:重新输入
- 正确:
- 展示棋盘中已经被摸过的坐标:重新输入
- 展示棋盘中没有摸过的坐标:
- 雷棋盘是雷,即1➡️游戏失败,展示雷棋盘
- 雷棋盘是安全的,即0➡️胜利次数win➕1
//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row , int col)
{
int x =0;
int y =0;
int win = 0;
while(win < row *col - numofboom)
{ printf("请输入坐标>");
scanf("%d %d", &x,&y);
if(x >= 1 && x <= row && y >=1&& y<= col)
{
if (show[x][y]!='*')
printf("输入坐标重复,请重新输入\n");
else if(mine[x][y]=='1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW,COL);
break;
}
else
{
int c = GetMineCount(mine, x,y);
show[x][y]=c+'0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
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);
}
最终结果
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define numofboom 10
//开始给棋盘赋值
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;
}
}
}
//展示棋盘
void DisplayBoard(char board[ROWS][COLS], int row ,int col)
{
int i = 0;
int j = 0;
printf("-----扫雷-----\n");
for (i = 0; i<= row;i++)
{
printf("%d ",i);
}
printf("\n");
for(i= 1;i <= row;i++)
{
printf("%d ",i);
for (j = 1 ;j<= col;j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
printf("--------------\n");
}
//布置雷
void SetMine(char board[ROWS][COLS],int row,int col)
{
int count = numofboom;
while(count)
{
int x = rand() % row +1;
int y = rand() % col +1;
if (board[x][y] =='0')
{
board[x][y]= '1';
}
count --;
}
}
//对周围雷的排查
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
return mine[x+1][y] + mine[x-1][y]+ mine[x][y-1]+ mine[x][y+1] + mine[x-1][y-1] + mine[x-1][y+1] + mine[x+1][y+1] + mine[x+1][y-1]- 8*'0';
}
//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row , int col)
{
int x =0;
int y =0;
int win = 0;
while(win < row *col - numofboom)
{ printf("请输入坐标>");
scanf("%d %d", &x,&y);
if(x >= 1 && x <= row && y >=1&& y<= col)
{
if (show[x][y]!='*')
printf("输入坐标重复,请重新输入\n");
else if(mine[x][y]=='1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW,COL);
break;
}
else
{
int c = GetMineCount(mine, x,y);
show[x][y]=c+'0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("输入坐标错误,请重新输入坐标\n");
}
}
}
//manu
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()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{ menu();
printf("请输入选项\n");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}while (input);
return 0;
}
加油加油
1486





