
扫雷游戏
 这个界面是不是很熟悉呢?这个就是扫雷游戏的界面了。但是我们用C语言只能用黑框框来实现了。不过问题不大,我们还是可以搞出来的。基本思路: 1、我们建立两个二维数组,一个用来存放雷,一个用来打印屏幕显示。 2、先搞个初始函数,把两个数组初始化为想要的字符,雷用字符 ’1‘ 表示,游戏框用字符 ‘*’ 表示,但是玩家只能看到显示数组,看不到存放雷的数据。 3、然后玩家就在键盘上输入坐标,我们再用坐标内的数据与存放雷的数组相比较,如果不是雷就一直玩下去,直到把雷全部找出来。如果是雷那么就扫雷失败。
游戏实现过程
游戏框架
我们要实现这个工程不妨建立一个头文件game.h 和两个c语言玩家 test.c 和 game.c 其中game.h 头文件存放函数的声明和包含一些其他头文件,;test.c 文件测试函数的功能;game.c 文件就具体的来实现函数的功能。 
我们玩游戏都有一个菜单给玩家选择,我们也不例外,给玩家一个选择的功能,并且搭建一个框架,然后再具体实现功能。代码如下:
void menu()
{
printf("**********************************\n");
printf("****** 恭喜你来到扫雷游戏 ****\n");
printf("********* 1.play *********\n");
printf("********* 0.exit *********\n");
printf("**********************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入你的选择:");
scanf("%d",&input);
switch (input)
{
case 1:game();
break;
case 0: printf("退出游戏\n");
break;
default:printf("选择错误,请重新选择:\n");
break;
}
} while (input);
return 0;
}
上面的代码基本逻辑就是玩家输入1就玩游戏,输入0就退出游戏,如果输入其他东西就重新回到菜单给玩家输入,直达玩家输入1或者0;所以我们只要把 里面的game()函数搞定就OK了。
数组的建立与分析
框架我们搞定了,接下来就是game()函数的具体实现了。 我们可以思考如果用一个数组来存放雷和打印棋盘是冲突的,非常难实现;所以用两个二维数组来做,一个用来存放雷,一个用来打印棋盘给玩家看到的。 在放雷数组中雷用字符 ‘1’ 表示,不是雷用 ‘0’ 表示。 棋盘数组中开始全部放字符 ‘*’ 类似于开始时界面。 判断是否扫到雷,我们只需要遍历坐标的周围8个位置是否有雷就可以了。  然后我们打印棋盘顺便把行列都打印出来 ,代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0, j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void Display(char board[ROWS][COLS], int row, int col)
{
int i = 0, j = 0;
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");
}
我们可以先测试一下: 
雷的存放与分析
我们数组初始化好了,接下来就是放雷了,我们先放10个雷吧。 然后用随机数生成并且放到数组中,代码如下:
void Set(char board[ROWS][COLS], int row, int col)
{
int count = EASY_CONUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
随机生成的雷存放如下: 
玩家的输赢分析
所以的基础已经准备好了,接下来就到玩家去下了。 玩家怎么输?怎么赢呢?其实玩家输很简单,只要输入的坐标是雷,那么就输了, 而赢却复杂一点,要判断棋盘数组中只剩下10个字符 ‘*’ 才能赢。 并且如果不是雷,我们还要统计该坐标周围一几个雷并且打印到棋盘上。 代码如下:
int Count(char mine[ROWS][COLS],int x,int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y + 1] +
mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
}
int IsWin(char show[ROWS][COLS])
{
int i = 0, j = 0;
int count = 0;
for (i = 1; i <= ROW; i++)
{
for (j = 1; j <= COL; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
return count;
}
void Find(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols)
{
while (1)
{
if (IsWin(show) == EASY_CONUNT)
{
printf("恭喜你,扫雷成功了\n");
break;
}
int x = 0, y = 0;
printf("请输入你的坐标:");
scanf("%d %d",&x,&y);
printf("\n");
if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
{
if (mine[x][y] == '1')
{
printf("扫雷失败\n");
Display(mine,ROW,COL);
break;
}
else if(show[x][y]=='*')
{
int ret = Count(mine, x, y);
show[x][y] = ret + '0';
Display(show, ROW, COL);
}
else
{
printf("你输入的坐标已经显示了,请重新输入\n");
}
}
else
{
printf("你输入的超出范围,请重新输入:\n");
}
}
}
游戏的全部代码
头文件game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_CONUNT 10
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void Display(char board[ROWS][COLS], int row, int col);
void Set(char board[ROWS][COLS], int row, int col);
void Find(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols);
源文件test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
Display(show, ROW, COL);
Set(mine, ROW, COL);
Display(mine, ROW, COL);
Find(mine, show, ROWS, COLS);
}
void menu()
{
printf("**********************************\n");
printf("********* 1.play *********\n");
printf("********* 0.exit *********\n");
printf("**********************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入你的选择:");
scanf("%d",&input);
switch (input)
{
case 1:game();
break;
case 0: printf("退出游戏\n");
break;
default:printf("选择错误,请重新选择:\n");
break;
}
} while (input);
return 0;
}
源文件game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0, j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void Display(char board[ROWS][COLS], int row, int col)
{
int i = 0, j = 0;
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 Set(char board[ROWS][COLS], int row, int col)
{
int count = EASY_CONUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
int Count(char mine[ROWS][COLS],int x,int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y + 1] +
mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
}
int IsWin(char show[ROWS][COLS])
{
int i = 0, j = 0;
int count = 0;
for (i = 1; i <= ROW; i++)
{
for (j = 1; j <= COL; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
return count;
}
void Find(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols)
{
while (1)
{
if (IsWin(show) == EASY_CONUNT)
{
printf("恭喜你,扫雷成功了\n");
break;
}
int x = 0, y = 0;
printf("请输入你的坐标:");
scanf("%d %d",&x,&y);
printf("\n");
if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
{
if (mine[x][y] == '1')
{
printf("扫雷失败\n");
Display(mine,ROW,COL);
break;
}
else if(show[x][y]=='*')
{
int ret = Count(mine, x, y);
show[x][y] = ret + '0';
Display(show, ROW, COL);
}
else
{
printf("你输入的坐标已经显示了,请重新输入\n");
}
}
else
{
printf("你输入的超出范围,请重新输入:\n");
}
}
}
游戏的执行:   欢迎各位在评论区探讨,点个赞呗!
|