目录
一、怎么实现?
一、怎么实现?
游戏大体框架构建->菜单、游戏主体->游戏主体用什么实现?->两个数组->一个显示(玩家所见)另外一个用来储存数据(存雷以及数据处理)->看玩家的选择错误与否->提示->主体需要一个循环来实现菜单以及游戏主体的显示->大体框架确认完毕。
void menu()//菜单
{
printf("--------------------\n");
printf("|******************|\n");
printf("|***** 1.play *****|\n");
printf("|***** 0.exit *****|\n");
printf("|******************|\n");
printf("--------------------\n");
}
void game()//游戏本体
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
Initboard(mine, ROWS, COLS,'0');
Initboard(show, ROWS, COLS, '*');
Getmine(mine, MINE);
//Showboard(mine, ROW, COL);
printf("--------------------\n");
Showboard(show, ROW, COL);
win(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf(" -扫雷游戏-\n");
game();
break;
case 0:
printf("退出成功!\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
二、game()主体的构建
构建大体框架->需要什么功能?->初始化->种地雷->查地雷->得到地雷数量的数据->判输赢条件。每次操作都需要判断是否踩到地雷->因此不如初始化存地雷数据的数组为‘1’和‘0’,‘1’代表雷‘0’代表没雷。大体确认完毕
代码如下:
void Initboard(char board[ROWS][COLS],int rows,int cols,char a)//初始化数组为a
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = a;
}
}
}
void Showboard(char board[ROWS][COLS], int row, int col)//打印扫雷的游戏棋盘
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n ———————————————————\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i);
for (int j = 1; j <= col; j++)
{
if(j!=col)
printf("%c ", board[i][j]);
else
printf("%c|", board[i][j]);
}
printf("\n");
}
printf(" ———————————————————\n");
}
void Getmine(char board[ROWS][COLS], int mine)//种地雷,种的数量为mine
{
int count = 0;
while (count < mine)
{
int x = rand() % 9 + 1;
int y = rand() % 9 + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count++;
}
}
}
int Countmine(char board[ROWS][COLS], int row, int col)//数周围的地雷数量
{
return (board[row - 1][col] + board[row-1][col-1] + board[row][col-1] + board[row+1][col-1] + board[row+1][col] +
board[row+1][col+1] + board[row][col+1] + board[row-1][col+1] - '0'*8 );
}
void flower(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* count)//递归查询周围地雷实现地雷游戏的遍地开花
{
if (row > 0 && row < ROWS && col>0 && col < COLS)//使数组不越距
{
if (show[row][col] == '*')//递归结束条件
{
if (Countmine(mine, row, col) == 0)//周围都空遍地开花
{
show[row][col] = ' ';//使其显示为空格
(*count)--;
flower(mine, show, row - 1, col, count);
flower(mine, show, row - 1, col - 1, count);
flower(mine, show, row, col - 1, count);
flower(mine, show, row + 1, col - 1, count);
flower(mine, show, row + 1, col, count);
flower(mine, show, row + 1, col + 1, count);
flower(mine, show, row, col + 1, count);
flower(mine, show, row - 1, col + 1, count);
}
else//周围不是全空则标出周围地雷数量
{
show[row][col] = Countmine(mine, row, col) + '0';
(*count)--;
}
}
}
}
void change(char mine[ROWS][COLS], int row, int col)//就是为了好看点^_^用来游戏结尾显示地雷
{
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= col; j++)
{
if (mine[i][j] == '1')
mine[i][j] = '$';
}
}
}
void win(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//判断输赢
{
int a = 0, b = 0;
int move = 81 - MINE;
while (move != 0)
{
printf("输入扫雷位置(空格隔开):");
scanf("%d %d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col&&show[a][b]=='*')//使数组不越距并且防止选同样的位置
{
if (mine[a][b] == '1')
{
system("cls");//清屏为了好看
change(mine, ROW, COL);
printf("你被炸4了!\n");
Showboard(mine, row, col);
break;
}
else
{
flower(mine, show, a, b, &move);
system("cls");
Showboard(show, row, col);
}
}
else
{
printf("输入错误!请重新输入! ");
}
}
if (move == 0)
{
system("cls");
printf("恭喜你!扫完了全部雷!\n");
change(mine, ROW, COL);
Showboard(mine, row, col);
}
}
三、重点在判输赢!
怎么算赢?主要在于玩家扫完所有雷,因此需要定义一个变量move来实现计数,move一开始的数量为9X9-地雷数量,玩家每动一步便-1直到为0跳出循环。重点在于遍地开花(选中的坐标包括周围共8个空位没有地雷)每找到一个就让他为空格,这也算是玩家动作也需让move-1;每多出来一个空以及标明附近地雷数量都要让move-1。
遍历递归函数
void flower(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* count)//递归查询周围地雷实现地雷游戏的遍地开花
{
if (row > 0 && row < ROWS && col>0 && col < COLS)//使数组不越距
{
if (show[row][col] == '*')//递归结束条件
{
if (Countmine(mine, row, col) == 0)//周围都空遍地开花
{
show[row][col] = ' ';//使其显示为空格
(*count)--;
flower(mine, show, row - 1, col, count);
flower(mine, show, row - 1, col - 1, count);
flower(mine, show, row, col - 1, count);
flower(mine, show, row + 1, col - 1, count);
flower(mine, show, row + 1, col, count);
flower(mine, show, row + 1, col + 1, count);
flower(mine, show, row, col + 1, count);
flower(mine, show, row - 1, col + 1, count);
}
else//周围不是全空则标出周围地雷数量
{
show[row][col] = Countmine(mine, row, col) + '0';
(*count)--;
}
}
}
}
判赢函数
void win(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//判断输赢
{
int a = 0, b = 0;
int move = 81 - MINE;
while (move != 0)
{
printf("输入扫雷位置(空格隔开):");
scanf("%d %d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col&&show[a][b]=='*')//使数组不越距并且防止选同样的位置
{
if (mine[a][b] == '1')
{
system("cls");//清屏为了好看
change(mine, ROW, COL);
printf("你被炸4了!\n");
Showboard(mine, row, col);
break;
}
else
{
flower(mine, show, a, b, &move);
system("cls");
Showboard(show, row, col);
}
}
else
{
printf("输入错误!请重新输入! ");
}
}
if (move == 0)
{
system("cls");
printf("恭喜你!扫完了全部雷!\n");
change(mine, ROW, COL);
Showboard(mine, row, col);
}
}
四、总体代码
game.h
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define MINE 10
#define ROWS ROW+2
#define COLS COL+2
void Initboard(char board[ROWS][COLS], int rows, int cols, char a);//初始化
void Showboard(char board[ROW][COL], int row, int col);//打印
void Getmine(char board[ROWS][COLS],int mine);//种地雷
void win(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//判赢
game.c
#define _CRT_SECURE_NO_WARNINGS 01
#include"game.h"
void Initboard(char board[ROWS][COLS],int rows,int cols,char a)//初始化数组为a
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = a;
}
}
}
void Showboard(char board[ROWS][COLS], int row, int col)//打印扫雷的游戏棋盘
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n ———————————————————\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i);
for (int j = 1; j <= col; j++)
{
if(j!=col)
printf("%c ", board[i][j]);
else
printf("%c|", board[i][j]);
}
printf("\n");
}
printf(" ———————————————————\n");
}
void Getmine(char board[ROWS][COLS], int mine)//种地雷,种的数量为mine
{
int count = 0;
while (count < mine)
{
int x = rand() % 9 + 1;
int y = rand() % 9 + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count++;
}
}
}
int Countmine(char board[ROWS][COLS], int row, int col)//数周围的地雷数量
{
return (board[row - 1][col] + board[row-1][col-1] + board[row][col-1] + board[row+1][col-1] + board[row+1][col] +
board[row+1][col+1] + board[row][col+1] + board[row-1][col+1] - '0'*8 );
}
void flower(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* count)//递归查询周围地雷实现地雷游戏的遍地开花
{
if (row > 0 && row < ROWS && col>0 && col < COLS)//使数组不越距
{
if (show[row][col] == '*')//递归结束条件
{
if (Countmine(mine, row, col) == 0)//周围都空遍地开花
{
show[row][col] = ' ';//使其显示为空格
(*count)--;
flower(mine, show, row - 1, col, count);
flower(mine, show, row - 1, col - 1, count);
flower(mine, show, row, col - 1, count);
flower(mine, show, row + 1, col - 1, count);
flower(mine, show, row + 1, col, count);
flower(mine, show, row + 1, col + 1, count);
flower(mine, show, row, col + 1, count);
flower(mine, show, row - 1, col + 1, count);
}
else//周围不是全空则标出周围地雷数量
{
show[row][col] = Countmine(mine, row, col) + '0';
(*count)--;
}
}
}
}
void change(char mine[ROWS][COLS], int row, int col)//就是为了好看点^_^用来游戏结尾显示地雷
{
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= col; j++)
{
if (mine[i][j] == '1')
mine[i][j] = '$';
}
}
}
void win(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//判断输赢
{
int a = 0, b = 0;
int move = 81 - MINE;
while (move != 0)
{
printf("输入扫雷位置(空格隔开):");
scanf("%d %d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col&&show[a][b]=='*')//使数组不越距并且防止选同样的位置
{
if (mine[a][b] == '1')
{
system("cls");//清屏为了好看
change(mine, ROW, COL);
printf("你被炸4了!\n");
Showboard(mine, row, col);
break;
}
else
{
flower(mine, show, a, b, &move);
system("cls");
Showboard(show, row, col);
}
}
else
{
printf("输入错误!请重新输入! ");
}
}
if (move == 0)
{
system("cls");
printf("恭喜你!扫完了全部雷!\n");
change(mine, ROW, COL);
Showboard(mine, row, col);
}
}
text.c
#define _CRT_SECURE_NO_WARNINGS 01
#include"game.h"
void menu()//菜单
{
printf("--------------------\n");
printf("|******************|\n");
printf("|***** 1.play *****|\n");
printf("|***** 0.exit *****|\n");
printf("|******************|\n");
printf("--------------------\n");
}
void game()//游戏本体
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
Initboard(mine, ROWS, COLS,'0');
Initboard(show, ROWS, COLS, '*');
Getmine(mine, MINE);
//Showboard(mine, ROW, COL);
printf("--------------------\n");
Showboard(show, ROW, COL);
win(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf(" -扫雷游戏-\n");
game();
break;
case 0:
printf("退出成功!\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}