扫雷游戏分为三个文件:test.c,game.c,game.h。
主要步骤简单讲解:
1.打印出菜单(较简单)
2.初始化棋盘
可以看出我们是用的9*9的棋盘,由扫雷游戏的基础规则可知应该要能够计算出非雷坐标的周围雷数总和,但是当我们创建一个9*9的二维数组时,在外围的一圈计算周围雷数总和容易导致越界情况的产生。所以我创建的是11*11的二维数组,来避免计算周围雷数总和时出现越界情况的产生。这里初始化时我是创建了两个数组,一个为mine数组,字符‘0’表示的是非雷,‘1’表示的是雷。一个是show数组,用来存放周围雷数的总和,并且在游戏中打印出来。初始化时在里面放入‘字符*’。
3.打印棋盘
利用for循环打印即可。注意打印出序号,方便游戏时输入位置坐标
4.填充雷
利用产生随机数的思想,产生1-9的数字即可
5.排查雷
看代码即可
注意:可以用1清屏函数在打印完菜单或者打印完show数组后清空屏幕,方便输入坐标,也让画面更简洁。
代码:
1.test.c代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//步骤:
//1.打印菜单
//2.初始化棋盘
//3.打印棋盘
//4.填充雷 ‘1’表示雷
//5.排查雷
void menu()
{
printf("\t\t***************** menu ****************\n\n\n");
printf("\t\t*****************1.play****************\n\n");
printf("\t\t*****************0.exit****************\n\n");
printf("\t\t***************************************\n\n");
}
void test()
{
int input = 0;
do
{
menu();
printf("请进行选择:》");
scanf("%d", &input);
system("cls"); //清屏,将菜单清空。
switch (input)
{
case 1:
game();
printf("\n");
printf("请选择是否继续:》\n");
break;
case 0:
printf("退出程序!");
break;
default:
printf("输入错误!请重新输入\n");
break;
}
} while (input); //刚好在input为时能够为否,退出程序
}
int main()
{
srand((unsigned int)rand(NULL));
test();
return 0;
}
2.game.c代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化数组
void intboard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int k = 0;
for (i = 0; i < rows; i++)
{
for (k = 0; k < cols; k++)
{
board[i][k] = set;
}
}
}
//打印数组
void printboard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int k = 0;
int j = 0;
printf("\n\n");
printf("*************扫雷*************\n");
for (j = 0; j <= row; j++) //打印出列号
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i); //打印出行号
for (k = 1; k <= col; k++)
{
printf("%c ", board[i][k]);
}
printf("\n");
}
printf("*************扫雷*************\n");
printf("\n\n");
}
//填充雷
void setboard(char board[ROWS][COLS], int row, int col)
{
int count = EASY;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
//计算输入坐标周围的雷总数
int sum(char mine[ROWS][COLS],int x,int y) //利用'1','0'在ASCII的关系计算出坐标周围的雷的个数
{
return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1]
+ mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}
//排查雷
void findboard(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 - EASY)
{
printf("请输入你要查找的坐标(用空格分隔) :》\n");
scanf("%d %d", &x, &y);
system("cls"); //循环中多次调用清屏函数,将列表清空。
if (x>0 && x<=row && y>0 && y<=col) //判断输入是否合法
{
if (show[x][y] != '*') //防御性措施,防止输入重复坐标
{
printf("输入重复!请重新输入\n");
continue;
}
else
{
if (mine[x][y] == '1')
{
printf("寄!\n");
printf("雷分布如下:》\n");
printboard(mine, ROW, COL);
break;
}
else
{
show[x][y] = sum(mine,x,y) + '0';
printboard(mine, ROW, COL);
win++;
}
}
}
else
{
printf("输入不合法!请重新输入\n");
}
}
if (win == row * col - EASY)
{
printf("恭喜你成功通关!\n");
printf("雷分布如下:》\n");
printboard(mine, ROW, COL);
}
}
void game()
{
char mine[ROWS][COLS] = { 0 }; //用来存放雷的位置
char show[ROWS][COLS] = { 0 }; //用来存放排查出的雷的信息
intboard(mine, ROWS, COLS, '0'); //初始化mine数组,'0'代表安全,'1'代表雷
intboard(show, ROWS, COLS, '*'); //初始化show数组
//printboard(mine, ROW, COL); //打印mine数组,可以通过其来查看雷的分布情况
printboard(show, ROW, COL); //打印show数组
setboard(mine,ROW,COL); //填充雷
findboard(mine,show,ROW,COL); //排查雷
}
3.game.h代码:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//9*9的棋盘
//为了避免边界处需要检验是否越界,所以创建11*11的数组
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY 10
#define MID 20
#define PROBLEM 50
//初始化数组
void intboard(char board[ROWS][COLS], int rows, int cols, char set);
//打印数组
void printboard(char board[ROWS][COLS], int row, int col);
//填充雷
void setboard(char board[ROWS][COLS], int row, int col);
//计算输入坐标周围的雷总数
int sum(char mine[ROWS][COLS], int x, int y); //利用'1','0'在ASCII的关系计算出坐标周围的雷的个数
//排查雷
void findboard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//扫雷游戏主体
void game();