简易扫雷的代码拆解
扫雷的逻辑
如果选择的位置不是雷,即显示周围雷的个数;如果是雷游戏结束,并显示雷的分布
1、打印菜单、进行选择
先打印一份菜单便于理解如何开始与退出游戏
void mune()
{
printf("**********************\n");
printf("*******1 开始*********\n");
printf("*******0 退出*********\n");
printf("**********************\n");
}
2、生成棋盘并初始化
1、生成棋盘
防止在读取周围雷的信息造成数组越界,我们将数组上下左右都增加一格:
既可以防止数组越界,又可以使数组的下标与编号一致。
char bomb[RS][CS] = { 0 };
char show[RS][CS] = { 0 };
将存放雷的信息与显示信息分开可以防止数据类型过多。
设置两个char类型的数组可以在初始化时使用一个函数就够了
2、初始化棋盘
初始化棋盘的函数
void set_chessboard(char arr[RS][CS], int r, int c, char ch)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
arr[i][j] = ch;
}
}
}
再调用函数初始化棋盘
set_chessboard(bomb, RS, CS, '0');
set_chessboard(show, RS, CS, '*');
3、布置雷
先生成2个一到九的随机数,分别表示行和列,再将存放雷的数组的信息进行修改,在修改前我们需要判断该位置是否被修改过了
使用rand和srand函数来生成随机数
srand((unsigned int)time(NULL));
void set_bomb(char arr[RS][CS], int r, int c)
{
int count = easy_count;
while (count)
{
int x = rand() % r + 1;
int y = rand() % c + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
使用count来计算已经放了多少雷
4、排查雷
通过输入的坐标来判断该位置是否为雷
1、该位置是雷
踩雷游戏结束
if (bomb[x][y] == '1')
{
printf("踩雷,游戏结束\n");
printf_chessboard(bomb, CS, RS);
break;
}
2、该位置不是雷
显示周围雷的个数
//计算周围雷的个数
int get_bomb_num(char arr[RS][CS], int x, int y)
{
int num = (arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1] +arr[x][y - 1] + arr[x][y + 1] +arr[x + 1][y - 1] + arr[x + 1][y] + arr[x + 1][y + 1] - 8 * '0');
return num;
}
{
int num = get_bomb_num(bomb, x, y);
show[x][y] = num + '0';
count--;
printf_chessboard(show, RS, CS);
}
3、输入的坐标不在棋盘范围内
显示输入错误重新输入
printf("输入错误,请重新输入:");
排除雷的代码
当未踩雷时,需要多次排查,所以应该使用循环,循环条件应为输入次数
int get_bomb_num(char arr[RS][CS], int x, int y)
{
int num = (arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1] +arr[x][y - 1] + arr[x][y + 1] +arr[x + 1][y - 1] + arr[x + 1][y] + arr[x + 1][y + 1] - 8 * '0');
return num;
}
void find_bomb(char bomb[RS][CS],char show[RS][CS],int r,int c)
{
//排查次数
int count = r * c - easy_count;
while(count)
{
printf("请输入排查的坐标:");
int x, y;
scanf("%d%d", &x, &y);
{
if (x > 0 && x < r && y>0 && y < c)
{
//踩雷,游戏结束
if (bomb[x][y] == '1')
{
printf("踩雷,游戏结束\n");
printf_chessboard(bomb, CS, RS);
break;
}
//不踩雷,显示雷的个数
else
{
int num = get_bomb_num(bomb, x, y);
show[x][y] = num + '0';
count--;
printf_chessboard(show, RS, CS);
}
}
else
printf("输入错误,请重新输入:");
}
}
}
至此,扫雷的基础框架已经完成
现在只需要在main函数中将函数组装起来即可
int main()
{
srand((unsigned int)time(NULL));
//生成棋盘
char bomb[RS][CS] = { 0 };
char show[RS][CS] = { 0 };
//初始化棋盘
set_chessboard(bomb, RS, CS, '0');
set_chessboard(show, RS, CS, '*');
//选择
int n = 0;
do
{
//菜单
mune();
printf("请选择:");
scanf("%d", &n);
switch (n)
{
case 1:
printf("游戏开始\n");
//打印棋盘
printf_chessboard(show, RS, CS);
//生成雷
set_bomb(bomb, R, C);
//printf_chessboard(bomb, CS, RS);
//排查雷
find_bomb(bomb, show, R, C);
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误请重新输入");
}
} while (n);
return 0;
}
为了方便多次玩,使用循环进行判断
方便代码的编写与修改,将函数分装为三个部分
game.h声明函数
#pragma once
#include<stdio.h>
#define R 9
#define C 9
#define RS 9+2
#define CS 9+2
#define easy_count 10
//菜单
void mune();
//初始化棋盘
void set_chessboard(char arr[RS][CS], int r, int c, char ch);
//打印棋盘
void printf_chessboard(char arr[RS][CS], int rs, int cs);
//布置雷
void set_bomb(char arr[RS][CS], int r, int c);
//显示雷的个数
int get_bomb_num(char arr[RS][CS], int x, int y);
//排查雷
void find_bomb(char bomb[RS][CS], char show[RS][CS], int r, int c);
game.c函数的实现
#include"game.h"
//打印菜单
void mune()
{
printf("**********************\n");
printf("*******1 开始*********\n");
printf("*******0 退出*********\n");
printf("**********************\n");
}
//初始化棋盘
void set_chessboard(char arr[RS][CS], int r, int c, char ch)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
arr[i][j] = ch;
}
}
}
//打印棋盘
void printf_chessboard(char arr[RS][CS], int rs, int cs)
{
int i = 0;
for (i = 0; i < CS-1; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i < rs-1; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j < cs-1; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//布置雷
void set_bomb(char arr[RS][CS], int r, int c)
{
int count = easy_count;
while (count)
{
int x = rand() % r + 1;
int y = rand() % c + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
//显示雷的个数
int get_bomb_num(char arr[RS][CS], int x, int y)
{
int num = (arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1] +arr[x][y - 1] + arr[x][y + 1] +arr[x + 1][y - 1] + arr[x + 1][y] + arr[x + 1][y + 1] - 8 * '0');
return num;
}
//排查雷
void find_bomb(char bomb[RS][CS],char show[RS][CS],int r,int c)
{
//排查次数
int count = r * c - easy_count;
while(count)
{
printf("请输入排查的坐标:");
int x, y;
scanf("%d%d", &x, &y);
{
if (x > 0 && x < r && y>0 && y < c)
{
//踩雷,游戏结束
if (bomb[x][y] == '1')
{
printf("踩雷,游戏结束\n");
printf_chessboard(bomb, CS, RS);
break;
}
//不踩雷,显示雷的个数
else
{
int num = get_bomb_num(bomb, x, y);
show[x][y] = num + '0';
count--;
printf_chessboard(show, RS, CS);
}
}
else
printf("输入错误,请重新输入:");
}
}
}
test.c整个扫雷的过程
#include"game.h"
int main()
{
srand((unsigned int)time(NULL));
//生成棋盘
char bomb[RS][CS] = { 0 };
char show[RS][CS] = { 0 };
//初始化棋盘
set_chessboard(bomb, RS, CS, '0');
set_chessboard(show, RS, CS, '*');
//选择
int n = 0;
do
{
//菜单
mune();
printf("请选择:");
scanf("%d", &n);
switch (n)
{
case 1:
printf("游戏开始\n");
//打印棋盘
printf_chessboard(show, RS, CS);
//生成雷
set_bomb(bomb, R, C);
//printf_chessboard(bomb, CS, RS);
//排查雷
find_bomb(bomb, show, R, C);
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误请重新输入");
}
} while (n);
return 0;
}