扫雷相信大家都玩过,今天我将使用C语言实现简单地扫雷。
#include <stdio.h>
/**
* @author: 张翊
* @TIME: 2021/5/4 8:38
* @Description:
*/
#ifndef UNTITLED_MINE_H
#define UNTITLED_MINE_H
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>
#include <stdlib.h>
#define row 9 //棋盘行数
#define col 9 //棋盘列数
#define rows row+2 //为方便计数,将棋盘行列各加2
#define cols col+2
#define COUNT 10 //地雷总数
int menu();//菜单函数
void game();//游戏逻辑函数啊
void InitBoard(char board[rows][cols], int ROW, int COL, char set);//初始化函数
void FindMine(char mine[rows][cols], char show[rows][cols], int ROW, int COL);//扫雷函数
void DisplayBoard(char board[rows][cols], int ROW, int COL);//展示棋盘函数
void SetMine(char board[rows][cols]);//布置地雷函数
int GetCount(char mine[rows][cols], int x, int y);//统计地雷个数函数
int Win(char show[rows][cols]);//判断是够获胜函数
#endif
/**
* @author: 张翊
* @TIME: 2021/5/4 8:38
* @Description:
*/
int main()
{
while (1)
{
int choice = menu();
switch (choice)
{
case 1:
game();//游戏实现
break;
case 2:
printf("谢谢您的使用,再见!");
return 0;
default:
system("cls");
printf("您的选择有误,请重新输入:\n");
}
}
}
int menu()
{
int input;
printf("**************************\n");
printf("**********1.play *********\n");
printf("**********2.exit *********\n");
printf("**************************\n");
printf("请选择:>");
scanf("%d", &input);
return input;
}
第一步,创建两个数组,一个是雷盘数组,一个是向用户展示的数组,两个数组大小相同。
第二步,初始化这两个数组。
第三步,布置地雷
第四步,扫雷
void game()
{
char mine[rows][cols] = {0};
char show[rows][cols] = {0};
InitBoard(mine, rows, cols, '0');
InitBoard(show, rows, cols, '*');
SetMine(mine);
DisplayBoard(show, row, col);
FindMine(mine, show, row, col);
}
通过传入不同的set,将两个数组初始化成不同的形式。
/**
* 初始化函数
* @param board 棋盘数组
* @param ROW 行数
* @param COL 列数
* @param set 初始符号
*/
void InitBoard(char board[rows][cols], int ROW, int COL, char set)
{
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
board[i][j] = set;
}
}
}
为方便输入坐标,再打印棋盘时同时打印行列坐标,并且只打印数组1-9索引的元素。
/**
* 打印雷盘
* @param board
* @param ROW
* @param COL
*/
void DisplayBoard(char board[rows][cols], int ROW, int COL)
{
//打印列号
for (int i = 0; i <= ROW; i++)
{
printf("%d ", i);
}
printf("\n");
//打印行号及雷盘
for (int i = 1; i <= COL; i++)
{
printf("%d ", i);
for (int j = 1; j <= COL; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
/**
* 布置雷盘
* @param board
*/
void SetMine(char board[rows][cols])
{
srand((unsigned int) time(NULL));//使用系统时间作为随机值的种子
int count = COUNT;//雷的个数
while (count)//控制雷个数
{
int x = rand() % row + 1;//x会在1-9之间随机生成一个值
int y = rand() % col + 1;//y会在1-9之间随机生成一个值
if (board[x][y] == '0')//避免重复放雷
{
board[x][y] = '1';//雷的放置用字符'1'表示
count--;//放置一个。地雷个数减1,直至0退出
}
}
}
/**
* 扫雷
* @param mine
* @param show
* @param ROW
* @param COL
*/
void FindMine(char mine[rows][cols], char show[rows][cols], int ROW, int COL)
{
//row和col传递过来的是ROW和COL,这里用x,y来控制数组下标。
int x = 0;
int y = 0;
while (1)
{
printf("请输入排雷的坐标:>>>");
scanf("%d %d", &x, &y);
//如果输入坐标合法
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//玩家输入的坐标埋放了雷,那么对不起,打印雷分布情况,游戏结束
if (mine[x][y] == '1')
{
printf("\n很不幸,您被炸死了!!!\n雷的分布情况如下:\n");
DisplayBoard(mine, row, col);
printf("-----------游戏结束----------\n\n");
break;
}
//如果玩家周围有雷,直接显示周围雷的个数。
else if (mine[x][y] == '0')
{
show[x][y] = GetCount(mine, x, y) + '0';
DisplayBoard(show, row, col);
if (Win(show) == 1)//判断此时雷盘剩余的*数目,如果等于雷数,则玩家排雷成功。
{
DisplayBoard(mine, row, col);
break;
}
}
}
else//如果输入坐标非法,提示
{
printf("您的坐标输入有误,请重新输入\n");
}
}
}
由于地雷二维数组中存放的数据为char型(’0’为无雷,‘1’为有雷),为方便统计个数,将周围==8个格子的值相加减去‘0’==即可(ASCII码计算)。
/**
* 计算周围八个格子中雷的个数
* @param mine
* @param x
* @param y
* @return
*/
int GetCount(char mine[rows][cols], int x, int y)
{
int count = 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';
return count;
}
int Win(char show[rows][cols])
{
int count = 0;
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= col; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
if (count == COUNT)//判断此时雷盘剩余的*数目,如果等于雷数,则玩家排雷成功。
{
printf("恭喜你成功排雷,太棒了,太棒了,送你一朵小红花!!!\n");
printf("雷的分布情况如下:\n");
return 1;
}
return 0;
}