扫雷游戏思路
首先,在写扫雷小游戏之前,我们要先了解她的游戏规则。扫雷顾名思义就是找到所有非地雷的格子,只有把所有的非地雷的各自全部找出来游戏才会胜利,在过程中踩到雷就会游戏失败。游戏是由方格组成的区域,电脑版的中是使用鼠标标记所要查看的格子,在下面的程序中,我们使用坐标实现选择,当我们选择之后,方格中会出现一个数字,这个数字代表这个方格周围隐藏几颗雷。
接下来,我们先看一下,程序运行起来以后的样子。
步骤
1、设置菜单,让玩家选择是否游戏
(1)、选择 1 ,游戏开始;
(2)、选择 0 ,退出游戏;
(3)、选择其他,输入不合法,重新输入。
注:当玩家完成一次游戏后,应再次弹出菜单,故使用do循环(循环体至少执行一次)。
所以主函数代码为:
int main()
{
int input = 0; //菜单选择控制变量
srand((unsigned)time(NULL)); //设置随机种子
do
{
meau();
printf("请选择:\n");
scanf_s("%d",&input);
swith(input)
{
case GAME:
printf("游戏开始!\n");
GameTest();
break;
case EXIT:
printf("退出游戏。\n");
break;
default:
printf("输入不合法,请重新输入。\n");
break;
}
}while(input);
}
其中菜单的打印函数 meau() 代码的实现为:
void meau()
{
printf("##############################################\n");
printf("########## 扫雷 ###########\n");
printf("########## 1、GAME 0、EXIT ###########\n");
printf("##############################################\n");
}
2、游戏测试的实现
(1)、选择开始游戏以后,首先应该弹出棋盘供玩家选择扫哪里的雷;
(2)、在棋盘中,有一部分是雷,一部分不是雷,故应该定义两个数组,一个是存雷数组(Mine[ ][ ]),一个为显示数组(Show[ ][ ])。
思路:首先,在Mine数组中,用字符‘0’代表没雷,用字符‘1’代表有雷,(这样设置的好处是方便在后面统计雷的个数),先用字符‘0’置满,然后调用srand函数,对数组中随机设置雷;
然后,在Show数组中,应其为显示数组,代表它是为了隐藏雷的位置,故应该用字符‘ * ’置满,在通过输入坐标 ( x , y ),来进行排雷。在排雷过程中,用‘0’~‘8’来表示所找点周围的雷的个数,用 ret 表示周围雷个数,并返给Show[x][y]显示在棋盘上,这是一个循环过程,直至扫除所有的雷。
下面,首先写出整个游戏谢恩师的逻辑:
void GameTest()
{
int x = 0, y = 0;
int n = 0;
int ret = 0;
char Show[ROWS][COLS] = { 0 };
char Mine[ROWS][COLS] = { 0 };
InitBoard(Show, ROWS, COLS, '*');
InitBoard(Mine, ROWS, COLS, '0');
PrintBoard(Show, ROW, COL);
while (1)
{
printf("请选择:>");
scanf_s("%d %d", &x, &y);
if (n == 0)
{
SetMine(Mine, ROWS, COLS, x, y);
}
if (x > 0 && x <= COL && y > 0 && y <= ROW)
{
ret = GetMineCount(Mine, x, y);
if (ret == -1)
{
printf("很遗憾,你被炸死了。\n");
PrintBoard(Mine, ROW, COL);
break;
}
else if (ret != -1)
{
Expend(Mine, Show, ROW, COL, x, y);
if (NotShowCount(Show, ROWS, COLS) == MINECOUNT)
{
printf("恭喜你,扫雷成功!\n");
PrintBoard(Show, ROW, COL);
break;
}
PrintBoard(Show, ROW, COL);
}
}
else
{
printf("输入不合法\n");
}
n++;
}
}
3、实现函数
通过上面两部分的分析,接下来只需要把各个函数实现
(1)代码一:初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0, j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
(2)代码二:打印棋盘
void PrintBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0, j = 0, z = 0;
for (i = 0; i <= col; i++)
{
printf(" %2d ", i);
}
printf("\n");
printf(" ");
for (i = 0; i < col; i++)
{
printf("--- ");
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf(" %2d |", i);
for (j = 1; j <= col; j++)
{
printf(" %c |", board[i][j]);
}
printf("\n");
printf(" ");
for (z = 0; z < col; z++)
{
printf("--- ");
}
printf("\n");
}
}
(3)代码三:布雷
void SetMine(char board[ROWS][COLS], int rows, int cols, int x, int y)
{
int ret1 = 0, ret2 = 0;
int count = 0;
while (count < MINECOUNT)
{
ret1 = rand() % (rows - 3) + 1;
ret2 = rand() % (cols - 3) + 1;
if (board[ret1][ret2] == '0')
{
if (ret1 != x && ret2 != y)
{
board[ret1][ret2] = '1';
count++;
continue;
}
}
}
}
(4)代码四:统计雷的个数
int GetMineCount(char board[ROWS][COLS], int x, int y)
{
if (board[x][y] == '1')
{
return -1;
}
else
{
return ((board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1]\
+ board[x][y - 1] + board[x][y + 1]\
+ board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1]) - 8 * ('0'));
}
}
(5)代码五:实现展开
void Expend(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col, int x, int y)
{
int count = 0;
int i = 0, j = 0;
if (board2[x][y] = '*')
{
count = GetMineCount(board1, x, y);
if (count != 0)
{
board2[x][y] = count + '0';
}
else
{
board2[x][y] = '0';
for (i = -1; i <= 1; i++)
{
for(j = -1; j <= 1; j++)
{
if ((x + i >= 1 && x + i <= ROW && y + j >= 1 && y + j <= COL) && (i != 0||j != 0))
{
Expend(board1, board2, ROWS, COLS, x + i, y + j);
}
}
}
}
}
}
(6)代码六:未展开的个数
int NotShowCount(char board[ROWS][COLS], int rows, int cols)
{
int i = 0, j = 0;
int count = 0;
for (i = 1; i <= rows-2; i++)
{
for (j = 1; j <= cols-2; j++)
{
if (board[i][j] == '*')
{
count++;
}
}
}
return count;
}
4、附上完整代码
头文件:game.h
#ifndef __GAME_01__
#define __GAME_01__
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINECOUNT 10
enum OPTION
{
EXIT,
GAME
};
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void PrintBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int rows, int cols, int x, int y);
int GetMineCount(char board[ROWS][COLS], int x, int y);
void Expend(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col, int x, int y);
int NotShowCount(char board[ROWS][COLS], int rows, int cols);
#endif
源文件1:game.c
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0, j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void PrintBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0, j = 0, z = 0;
for (i = 0; i <= col; i++)
{
printf(" %2d ", i);
}
printf("\n");
printf(" ");
for (i = 0; i < col; i++)
{
printf("--- ");
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf(" %2d |", i);
for (j = 1; j <= col; j++)
{
printf(" %c |", board[i][j]);
}
printf("\n");
printf(" ");
for (z = 0; z < col; z++)
{
printf("--- ");
}
printf("\n");
}
}
void SetMine(char board[ROWS][COLS], int rows, int cols, int x, int y)
{
int ret1 = 0, ret2 = 0;
int count = 0;
while (count < MINECOUNT)
{
ret1 = rand() % (rows - 3) + 1;
ret2 = rand() % (cols - 3) + 1;
if (board[ret1][ret2] == '0')
{
if (ret1 != x && ret2 != y)
{
board[ret1][ret2] = '1';
count++;
continue;
}
}
}
}
int GetMineCount(char board[ROWS][COLS], int x, int y)
{
if (board[x][y] == '1')
{
return -1;
}
else
{
return ((board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1]\
+ board[x][y - 1] + board[x][y + 1]\
+ board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1]) - 8 * ('0'));
}
}
void Expend(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col, int x, int y)
{
int count = 0;
int i = 0, j = 0;
if (board2[x][y] = '*')
{
count = GetMineCount(board1, x, y);
if (count != 0)
{
board2[x][y] = count + '0';
}
else
{
board2[x][y] = '0';
for (i = -1; i <= 1; i++)
{
for(j = -1; j <= 1; j++)
{
if ((x + i >= 1 && x + i <= ROW && y + j >= 1 && y + j <= COL) && (i != 0||j != 0))
{
Expend(board1, board2, ROWS, COLS, x + i, y + j);
}
}
}
}
}
}
int NotShowCount(char board[ROWS][COLS], int rows, int cols)
{
int i = 0, j = 0;
int count = 0;
for (i = 1; i <= rows-2; i++)
{
for (j = 1; j <= cols-2; j++)
{
if (board[i][j] == '*')
{
count++;
}
}
}
return count;
}
源文件2:test.c
#include "game.h"
void GameTest()
{
int x = 0, y = 0;
int n = 0;
int ret = 0;
char Show[ROWS][COLS] = { 0 };
char Mine[ROWS][COLS] = { 0 };
InitBoard(Show, ROWS, COLS, '*');
InitBoard(Mine, ROWS, COLS, '0');
PrintBoard(Show, ROW, COL);
while (1)
{
printf("请选择:>");
scanf_s("%d %d", &x, &y);
if (n == 0)
{
SetMine(Mine, ROWS, COLS, x, y);
}
if (x > 0 && x <= COL && y > 0 && y <= ROW)
{
ret = GetMineCount(Mine, x, y);
if (ret == -1)
{
printf("很遗憾,你被炸死了。\n");
PrintBoard(Mine, ROW, COL);
break;
}
else if (ret != -1)
{
Expend(Mine, Show, ROW, COL, x, y);
if (NotShowCount(Show, ROWS, COLS) == MINECOUNT)
{
printf("恭喜你,扫雷成功!\n");
PrintBoard(Show, ROW, COL);
break;
}
PrintBoard(Show, ROW, COL);
}
}
else
{
printf("输入不合法\n");
}
n++;
}
}
void meau()
{
printf("#######################################\n");
printf("########## 扫雷 ##########\n");
printf("#### 1.game ######## 0.exit ####\n");
printf("#######################################\n");
}
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meau();
scanf_s("%d", &input);
switch(input)
{
case GAME:
printf("开始游戏!\n");
GameTest();
break;
case EXIT:
printf("退出游戏。\n");
break;
default:
printf("输入不合法,请重新输入。\n");
break;
}
} while (input);
return 0;
}