学习了一部分的C语言知识,是时候该用来做做扫雷了,接下来我会详细阐述游戏的实现过程
目录
1、扫雷实现的大致思路
玩扫雷游戏时,点击一个方格时,如果这个不是地雷,这个格子会显示周围3*3八个格子的总共地雷数目,只到所有不是雷的格子被找出来的时候,提示游戏结束,找出了所有的雷。我们可以用两个正方形数组,其中一个数组是给玩家看的,不显示地雷位置,另一个数组是隐藏起来的,用于存储地雷所在位置,直到用户输入雷的位置时,才显示这个隐藏数组。如下图
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
* | * | * | * | * | * | * | * | * |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
上面分别表示了给用户显示的数组,和隐藏的用于存储地雷位置的数组,第二个数组用‘1’,表示雷的位置。接下来解释代码的具体写法
2、扫雷的代码实现
(1)首先我们要打印出来游戏的一个目录,用户输入1开始游戏,输入0退出游戏代码如下:
//text.c
void menu(void) {
printf("**************************\n");
printf("******1.play 0.exit ******\n");
printf("**************************\n");
}
(2)然后我们可以通过一个switch语句来判断是否进入游戏
//text.c
int main() {
menu();
int input = 0;
do {
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
return 0;
}
其中的game()函数用于包含整个游戏的主体
//text.c
void game(void) {
//初始化棋盘
char boardplay[ROWS][COLS];
char boardhide[ROWS][COLS];
chessboard(boardplay,boardhide,'*','0');
}
(3)chessboard()函数用于初始化棋盘,boardplay[ROWS][COLS]表示显示给用户的数组,boardhide[ROWS][COLS]是隐藏起来的数组,ROWS和COLS分别用来定义数组的行和列
//game.c
void chessboard(char arr1[ROWS][COLS], char arr2[ROWS][COLS], char show, char mine) {
int i = 0;
int j = 0;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < ROWS; j++) {
arr1[i][j] = show;
arr2[i][j] = mine;
}
}
}
(4)接下来放置雷
//text.c
void game(void) {
//初始化棋盘
char boardplay[ROWS][COLS];
char boardhide[ROWS][COLS];
chessboard(boardplay,boardhide,'*','0');
//放雷
putmine(boardhide,'1');
}
putmine()函数表示随机放置雷,实现如下:
//game.c
void putmine(char arr[ROWS][COLS], char mine1) {
srand((unsigned int)time(NULL));
int count1 = COUNT;
while (count1 > 0) {
int x = rand() % ROWS;
int y = rand() % COLS;
if (arr[x][y] != mine1&&x>0&&x<ROW&&y>0&&y<COL) {
arr[x][y] = mine1;
count1--;
}
}
}
这里需要用到随机数x y分别表示了用户输入的x 与 y坐标COUNT表示需要设置雷的总数,把这个值放置在count当中,用一个while循环来布置此数目的雷,并且,布置之前要判断这个位置是否被布置,并且在一定的范围当中,下面的代码是定义关于ROW COL COUNT COLS ROWS 的值,
//game.h
#define ROWS 11
#define COLS 11
#define ROW ROWS-1
#define COL ROWS-1
#define COUNT 10;
(4)下面解释为什么这几个值要这样设置
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
如上图,行数和列数都是11行,生成雷的位置和用户实际操作的位置是中间的9*9的位置,这样做是为了后面用户输入坐标时,方便计算用户所输入坐标位置周围雷的个数,比如上图绿色所框选的位置,用户输入了绿色3*3中间所在的位置,接下来就应该显示这个位置周围雷的数目,我们就可以把中心周围位置的字符全部加起来-7 * ‘0’,然后再打印出来,这样可以得到周围雷的数目了,这里没有看懂的读者可以参考一下ASCII码表中‘1’~‘9’所对应的ASCII码。
(5)再来打印出来用户看到的数组
//text.c
void game(void) {
//初始化棋盘
char boardplay[ROWS][COLS];
char boardhide[ROWS][COLS];
chessboard(boardplay,boardhide,'*','0');
//放雷
putmine(boardhide,'1');
//打印用户看到数组
showmine(boardplay);
}
showmine()函数的实现具体如下,注意只需要打印中间9*9的数组,所需代码如下
//game.c
void showmine(char arr[ROWS][COLS]) {
for (int i = 0; i <= 9; i++) {
printf("%d ", i);
}
printf("\n");
for (int i = 1; i < ROW; i++) {
printf("%d ", i);
for (int j = 1; j < COL; j++) {
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
(6)让用户输入所选坐标,一直到用户找出所有的雷或者踩雷
//text.c
void game(void) {
//初始化棋盘
char boardplay[ROWS][COLS];
char boardhide[ROWS][COLS];
chessboard(boardplay,boardhide,'*','0');
//放雷
putmine(boardhide,'1');
//用户看到的雷
showmine(boardplay);
//用户输入雷的坐标
guessmine(boardplay,boardhide);
}
guessmine()函数具体实现如下:
//game.c
void guessmine(char arr1[ROWS][COLS], char arr2[ROW][COLS]) {
int input1 = 0;
int input2 = 0;
int count = (COL - 1)* (ROW - 1)-COUNT;
while(1){
scanf("%d %d", &input1, &input2);
if (input1 >= 1 && input1 <= 9 && input2 >= 1 && input2 <= 9) {
if (arr2[input1][input2] == '1') {
printf("很遗憾,你被炸死了。\n");
showmine(arr2);
break;
}
else {
arr1[input1][input2] = arr2[input1 - 1][input2 - 1] + arr2[input1][input2 - 1]
+ arr2[input1 + 1][input2 - 1] + arr2[input1 + 1][input2] + arr2[input1 + 1][input2 + 1]
+ arr2[input1][input2 + 1] + arr2[input1 - 1][input2 + 1] + arr2[input1 - 1][input2] - 7 * '0';
count--;
system("cls");
showmine(arr1);
if (count == 0) {
printf("恭喜你,通关了\n");
showmine(arr2);
break;
}
}
}
else {
printf("坐标非法,请重新输入\n");
}
}
system("cls")可以提高用户的游戏,避免出现太多的扫雷面板,所用的库函数是#include<Window.h>扫雷程序就完成啦。
3、下面是所有代码
//text.c
#include "game.h"
void menu(void) {
printf("**************************\n");
printf("******1.play 0.exit ******\n");
printf("**************************\n");
}
void game(void) {
//初始化棋盘
char boardplay[ROWS][COLS];
char boardhide[ROWS][COLS];
chessboard(boardplay,boardhide,'*','0');
//放雷
putmine(boardhide,'1');
showmine(boardplay);
//showmine(boardhide);
guessmine(boardplay,boardhide);
}
int main() {
menu();
int input = 0;
do {
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
return 0;
}
//game.c
#include "game.h"
#include<Windows.h>
void chessboard(char arr1[ROWS][COLS], char arr2[ROWS][COLS], char show, char mine) {
int i = 0;
int j = 0;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < ROWS; j++) {
arr1[i][j] = show;
arr2[i][j] = mine;
}
}
}
void putmine(char arr[ROWS][COLS], char mine1) {
srand((unsigned int)time(NULL));
int count1 = COUNT;
while (count1 > 0) {
int x = rand() % ROWS;
int y = rand() % COLS;
if (arr[x][y] != mine1&&x>0&&x<ROW&&y>0&&y<COL) {
arr[x][y] = mine1;
count1--;
}
}
}
void showmine(char arr[ROWS][COLS]) {
for (int i = 0; i <= 9; i++) {
printf("%d ", i);
}
printf("\n");
for (int i = 1; i < ROW; i++) {
printf("%d ", i);
for (int j = 1; j < COL; j++) {
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
void guessmine(char arr1[ROWS][COLS], char arr2[ROW][COLS]) {
int input1 = 0;
int input2 = 0;
int count = (COL - 1)* (ROW - 1)-COUNT;
while(1){
scanf("%d %d", &input1, &input2);
if (input1 >= 1 && input1 <= 9 && input2 >= 1 && input2 <= 9) {
if (arr2[input1][input2] == '1') {
printf("很遗憾,你被炸死了。\n");
showmine(arr2);
break;
}
else {
arr1[input1][input2] = arr2[input1 - 1][input2 - 1] + arr2[input1][input2 - 1]
+ arr2[input1 + 1][input2 - 1] + arr2[input1 + 1][input2] + arr2[input1 + 1][input2 + 1]
+ arr2[input1][input2 + 1] + arr2[input1 - 1][input2 + 1] + arr2[input1 - 1][input2] - 7 * '0';
count--;
system("cls");
showmine(arr1);
if (count == 0) {
printf("恭喜你,通关了\n");
showmine(arr2);
break;
}
}
}
else {
printf("坐标非法,请重新输入\n");
}
}
}
//game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROWS 11
#define COLS 11
#define ROW ROWS-1
#define COL ROWS-1
#define COUNT 10;
void chessboard(char arr1[ROWS][COLS], char arr2[ROWS][COLS], char show ,char mine);
void putmine(char arr[ROWS][COLS], char mine1);
void showmine(char arr[ROWS][COLS]);
void guessmine(char arr1[ROWS][COLS],char arr2[ROW][COLS]);