在实现这种小游戏时,每实现一个功能我们都要先检一下是否有bug,一个功能一个功能的实现起来。
void menu()
{
printf("********************\n");
printf("**1.play 0.exit**\n");
printf("********************\n");
}
int main()
{
srand((unsigned int)time(NULL));//电脑随机布置雷的位置
int input = 0;
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) 由于要防止棋盘周围雷的提示个数与用1表示雷混淆,所以我们要准备两个棋盘。一个棋盘随机布置雷,另一个棋盘用来排查雷的个数。字符1表示雷,字符0表示不是雷。
(2) 考虑到用户落子于棋盘边缘的时候,我们也要排查雷的个数,如果是99的数组,统计周围8个位置时,就会造成越界,所以我们要准备的是1111的两个棋盘(辅助统计),但是我们展示给用户的还是99的棋盘。
(3)准备两个数组。
一个棋盘全部初始化为字符0(还没布置雷);
一个棋盘全部初始化为字符(还没排查雷,还没开始游戏)
//这是调用的函数
//初始化两个数组
//一个初始化为'0'(表示还没布置雷)
//InitBoard(mine, ROWS, COLS,'0');
//一个初始化为'*'(表示还没开始排查)
//InitBoard(show, ROWS, COLS,'*');
//实现初始化棋盘的函数
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0;
int j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
board[i][j] = set;
}
}
}
注意我们要打印(展示)的棋盘是9x9的,一个打印全是0(还没布雷)的棋盘,一个打印全是*的棋盘。初始化完棋盘后,先打印出来看看能不能实现。
//打印棋盘
//Display(mine, ROW, COL);
//Display(show, ROW, COL);
//打印棋盘
void Display(char board[ROWS][COLS], int row, int col)
{
//我们要打印的是9*9的棋盘
int i = 0;
int j = 0;
printf("----------扫雷游戏---------\n");
//优化棋盘--打印列数
for (i = 0; i <= col; 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");
}
打印结果展示:
注意是在9*9的棋盘上布置雷。布置完之后可以把mine数组打印出来看看每次是不是随机布置的
//在9*9的棋盘上布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//布置10个雷
int count = boom;
while (count)
{
int x = rand() % 9 + 1;//1-9
int y = rand() % 9 + 1;//1-9
if (mine[x][y] == '0')//如果这个位置还没有布置雷,这个坐标才能布置雷
{
mine[x][y] = '1';
count--;
}
}
}
排查雷我们需要考虑玩家输入的坐标是否合法,是否已经落子,并且我们要从mine数组中获取用户输入坐标周围的雷的个数,即获取雷的个数,然后放在show数组的对应位置中。(注意我们获得的是数字,而我们需要的字符)
int get_Mine(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';
}
从ASCII码表中可得’0’的值为48,’1’的值为49,而我们的数字0就是0,1就是1,即数字和字符相差48,即’0’的值。所以如果要把数字转换成字符,就把数字加上’0’,如何以字符的形式打印,若要把字符转换成数字,则减去’0’.
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int win = 0;//赢的情况-排查出ROW*COL-boom
while (win<ROW*COL-boom)
{
printf("请输入你要排查的坐标:");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);//1-9
if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
{
if (show[x][y] != '*')
{
printf("此坐标已排查过了\n");
}
else if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
Display(mine, ROW, COL);
break;
}
else
{
//统计这个坐标周围有几个雷
//注意我们得到的是数字3,而我们要的是字符'3',才能存到字符数组show中
int count= get_Mine(mine, x, y);
show[x][y] = count + '0';
Display(show, ROW, COL);
win++;
}
}
else
{
printf("坐标输入不合法,请重新输入\n");
}
}
if (win == ROW * COL - boom)
{
printf("恭喜你!排雷成功!\n");
Display(mine, ROW, COL);
}
}
即排出win==ROW*COL-雷的个数
//头文件
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//展示棋盘
#define ROW 9
#define COL 9
//辅助棋盘
#define ROWS ROW+1
#define COLS COL+2
//想布置几个雷就布置几个雷
#define boom 70
//函数声明
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);
//打印棋盘
void Display(char board[ROWS][COLS], int row, int col);
//布置雷 布置雷的数组
void SetMine(char mine[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//实现初始化棋盘的函数
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0;
int 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)
{
//我们要打印的是9*9的棋盘
int i = 0;
int j = 0;
printf("----------扫雷游戏---------\n");
//优化棋盘--打印列数
for (i = 0; i <= col; 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");
}
//在9*9的棋盘上布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//布置10个雷
int count = boom;
while (count)
{
int x = rand() % 9 + 1;//1-9
int y = rand() % 9 + 1;//1-9
if (mine[x][y] == '0')//如果这个位置还没有布置雷,这个坐标才能布置雷
{
mine[x][y] = '1';
count--;
}
}
}
int get_Mine(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';
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int win = 0;//赢的情况-排查出ROW*COL-boom
while (win<ROW*COL-boom)
{
printf("请输入你要排查的坐标:");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);//1-9
if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
{
if (show[x][y] != '*')
{
printf("此坐标已排查过了\n");
}
else if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
Display(mine, ROW, COL);
break;
}
else
{
//统计这个坐标周围有几个雷
//注意我们得到的是数字3,而我们要的是字符'3',才能存到字符数组show中
int count= get_Mine(mine, x, y);
show[x][y] = count + '0';
Display(show, ROW, COL);
win++;
}
}
else
{
printf("坐标输入不合法,请重新输入\n");
}
}
if (win == ROW * COL - boom)
{
printf("恭喜你!排雷成功!\n");
Display(mine, ROW, COL);
}
}
#include"game.h"
void menu()
{
printf("********************\n");
printf("**1.play 0.exit**\n");
printf("********************\n");
}
void game()
{
//布置雷的数组
char mine[ROWS][COLS] = { 0 };
//排查雷的数组
char show[ROWS][COLS] = { 0 };
//初始化两个数组
//一个初始化为'0'(表示还没布置雷)
InitBoard(mine, ROWS, COLS,'0');
//一个初始化为'*'(表示还没开始排查)
InitBoard(show, ROWS, COLS,'*');
//打印棋盘
Display(mine, ROW, COL);
Display(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
Display(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));//电脑随机布置雷的位置
int input = 0;
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;
}