首先直接让大家看一下具体实现情况:
游戏开始界面,1进行游戏,0退出游戏。
图1.
开始玩游戏,随意选择一个坐标,若这个坐标不是雷,游戏不会终止,并且这个坐标显示出来的数字是这个坐标周围雷的个数。如图所示,选择坐标(1,1)。这个坐标不是雷,游戏并没有终止,并且此时显示出了数字0,说明这个位置周围没有雷。
图2.
当我们踩到雷的时候,游戏就会结束,并且显示所有雷的位置信息,如图所示:
图3.
显示出来的棋盘中,1代表的是雷,0代表的是空白位置。
当把雷全部排完,游戏结束,这是也会显示雷的位置,同样的,1代表雷,0代表空白的位置。这里我把雷设置成了80个,以便于结束游戏给大家展示,如图所示:
图4.
展示和实践的分界线
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上就是扫雷游戏的实现过程
那么我们如何写出扫雷游戏呢?
首先,看到图一
这个是一个游戏的界面,分成两部分组成。
第一部分:上面的图标(游戏菜单menu)
众所周知,这些图标可以用 printf() 这个函数打印出来
如图所示:
第二部分:请选择:(要输入的内容)
相同的, “请选择:” 这个文字加符号可用 printf() 函数打印出来
而要想输入内容到这个程序里面该用什么呢?当然使用的是scanf()函数
如图所示
这里,定义一个函数menu()来显示游戏界面的菜单,使用的时候直接在main方法里面调用就行。
而scanf()和各种循环直接放在main()方法里面使用,具体效果如下:
到这里,游戏界面和选择选项基本完成。
==================================================================================================================================================
然后,看到图2:
分析:
一:看到第一行(--------扫雷游戏---------),这个部分不必多说,直接用printf()函数打印出来。
二:看到数字行列的0 1 2 3 4 5 6 7 8 9 ,这些标志方便后面坐标的使用。一样的,可以用printf()函数打印出来。
三:看到 “ * ” , 这些其实可以用数组将它们打印出来,所以得用到数组。
四:看到“请输入要查找的数据:”,这里也是要用到printf()函数,并且输入要使用到scanf()函数。
开始实现:
这里提前弄好三个文件:
test.c game.c game.h 三个文件 方便函数的定义和使用,并且能让代码看起来更加清晰明了。
test.c:游戏具体的逻辑实现
game.c:具体的函数实现
game.h:数据的声明和函数的定义
开始定义数组:
第一个数组:mine数组(存放布置好的雷)
第二个数组:show数组(展示排查出来的雷的信息)
本因如图:
实际上,为了方便,与后面的计算,会演变成:
test.c
game.h
问题一:为什么定义行和列为9之后,还需要定义行和列为11?
回答:因为后面会涉及到统计周围雷的个数的计算,所以至少要扩大到11行11列的范围进行初始化
如图所示:
深绿色格子是扩大的范围,所以总共加起来要有11行11列,但实际上只需要布置雷在9*9的格子上
问题二:为什么要定义ROWS和COLS,这些,而不直接使用9或者11
回答:最主要的原因是方便,不仅是使用方便,修改也方便。
开始初始化棋盘:
初始化棋盘函数InitBoard。在game.h定义生命,在game.c把这个函数具体实现,在test.c中使用。
game.h
game.c
test.c
初始化棋盘算是全部完成了!!!!!!!!!!!!
开始布置雷:
布置雷的函数SetMine同样的
game.h:
game.c:
test.c:
随机布置雷就必定要用srand函数,需要头文件time.h
至此,布置雷这个过程就已经完成了。
打印棋盘:
定义一个打印棋盘的方法DisplayBoard
具体方法如下(别忘了在game.h定义声明)、
game.c
查找雷:
FindMine
game.c:
=============================================================================================================================================================================================================================================================================================================================================================================
游戏整体代码:
test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
#include <stdio.h>
void menu()
{
printf("********************************\n");
printf("*****1.play 0.exit*****\n");
printf("********************************\n");
printf("\n");
}
void game()
{
char mine[ROWS][COLS];//存放布置好的雷
char show[ROWS][COLS];//展示排查出来的雷的信息
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');//mine数组全为0
InitBoard(show, ROWS, COLS, '*');//show数组全为*
//布置雷
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("\n退出游戏\n");
break;
default:
printf("\n选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
game.c
#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 SetMine(char board[ROWS][COLS], int row, int col)
{
//布置10个雷
//生成随机的坐标
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("------扫雷游戏------\n");
for (i = 0; i <= col; i++)
{
printf("%d ",i);//打印行坐标
}
printf("\n");
for (i = 1; i < row; i++)
{
printf("%d ", i);//打印列坐标
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
//统计周围雷的个数
int GetMineCount(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 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("很遗憾你被炸死了");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//该坐标不是雷,统计周围有几个雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐标非法,请重新输入");
}
}
if (win==row*col-EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//布置雷
void SetMine(char board[ROWS][COLS],int row,int col);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);