一.扫雷游戏模式设计
1.游戏区包括雷区、地雷计数器和计时器,确定大小的矩形雷区中随机布置一定数量的地雷,玩家需要尽快找出雷区中的所有不是地雷的方块,而不许踩到地雷。
2.当玩家点击一个方格判断是否为雷时:
(1)为雷区:被炸死,游戏结束:
(2)不为雷区:该方块会显示一个数字,表示该方块周围一圈共8个方块中雷的数量。
3.必须将所有雷找出,游戏才能结束。
二.代码编写逻辑
1.在main函数中用do....while循环,来设置游戏的菜单,来判断开始游戏还是结束游戏
2.设置menu函数打印菜单
3.创造game函数,在其中设计游戏程序;
为了方便,创造game.cpp和game.h文件,将程序中用到的函数存放在game.cpp中,text.cpp在 使用时只需引用game.h。
4.game函数
(1)对于这个扫雷游戏我们需要在棋盘中得到两种信息:<1>l雷的位置 <2>l非雷位置的方块显示的数字,这是这个游戏运行的关键。为了方便设置mine数组用以布置雷,设置show数组用以显示数字。
(2)先声明本文提供的代码是以设置9*9表格,10个雷为例的扫雷游戏;用ROW与COL表示行与列。
(3)在刚刚介绍规则时其实有特殊情况,例如上图显示" ? "的方格在表格边缘处,计算它周围的方格是否有雷就不需要计算8个那么多,但为处理这类特殊情况编写过多的代码实在增加任务量且无多大意义,效率太低,所以需要换一个思路,如下图
在表格外面再加一圈,使其变成11*11的表格,并且非雷区(包括最外圈)全赋值0,雷赋值1,
这样处理时计算雷的数量就会方便很多,但在显示时只显示中间9*9的表格就行了。
在game.h中如下设置
5.game函数详解
(1)初始化棋盘
(2)布置雷
用rand函数生成一个随机数%9产生o~8的随机数再加一就是产生1~9的随机数;每生成一个雷count减一,count为0循环结束,雷布置完成。
在game.h中定义 EASY_COUNT 为雷的个数。
3.输入坐标
4.排雷
布置雷的时候用字符“1”,“1”的ASC||值为49,“0”的ASC||值为48,“1”-'0"=1
三.总结
这个游戏算是编程入门后的一个小挑战,挺有意思,他所用到的知识量没我想象中那么多,里面用到的知识并不难理解,难在思路上,如何构思,好的思路确实能减轻工作量。
如果大家有建议感谢留言。
最后全部代码奉上:
text.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"game.h"
void menu()
{
printf("******************************\n");
printf("********* 1.play *********\n");
printf("********* 0.exit *********\n");
printf("******************************\n");
}
void game()
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//DisplayBoard(mine, ROW, COL);
SetMine(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
FindMine(mine, show, ROW, COL);
}
int main()
{
int input=0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("推出游戏");
break;
defaut:
printf("输入错误,重新输入");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define EASY_COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("-------- 扫雷 --------\n");
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
int j = 0;
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
void SetMine(char board[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;//0~8+1-->1~9
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
return 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';
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < row * col - EASY_COUNT)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
if (show[x][y] != '*')
{
printf("该坐标已经被排查过了,无需再排查\n");
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
}
else
{
printf("输入的坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}