一,游戏规则
盘面上有许多方格,方格中随机分布着一些雷。你的目标是避开雷,打开其他所有格子。你可以任意选择一个格子将其打开。打开一个格子后,如果有雷则游戏结束,如果没有雷,则该格子会显示附近区域的雷的个数,你需要继续选择格子进行打开,直至排除所有的雷为止。
在C语言中,我们选择用以下元素来进行:
棋盘——9*9二维数组
有雷格子——“1”
无雷格子——“0”
未打开格子——“*”
二,基本思路
1,创建一个游戏初始界面
2,创建一个给用户看的9*9大小的棋盘【二维数组】
3,创建一个实际进行操作的棋盘,用于埋雷,计算周围雷数,大小需设置为11*11
(设置为11*11的原因:便于计算周围雷数时对边界格子的操作,防止越界)
4,初始化棋盘,显示给用户的棋盘中所有格子用“*”表示,实际操作的棋盘全部用“0”表示
5,进行埋雷,设置雷的个数(简单模式为10个,困难模式为30个),利用随机数随机生成雷的位置,将有雷的格子标记为“1”
7,进行排雷,打开一个非雷格子后,统计该格子周围雷的个数,并显示在该格子中。当遇到雷或者躲开所有雷时,游戏结束,显示所有雷的位置。
三,代码实现
头文件(game.h)
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define Easy_count 10
#define Hard_count 30
#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 ShowBoard(char board[Rows][Cols], int rows, int cols);
//难度选择
int choice(int input);
//布置雷
void SetMine(char board[Rows][Cols], int row, int col,int count);
//排查雷
void FindMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col,int count);
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 ShowBoard(char board[Rows][Cols], int rows, int cols) {
printf("--------扫雷游戏---------\n");
int i = 0;
for (i = 0; i <= cols; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= rows; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= cols; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
int choice(int input) {
int count1 = 0;
if (input == 1) {
count1 = Easy_count;
}
else {
count1 = Hard_count;
}
return count1;
}
void SetMine(char board[Rows][Cols], int row, int col,int count){
while (count) {
int x = rand() % Row + 1;
int y = rand() % Col + 1;
if (board[x][y] = '0')
{
board[x][y] = '1';
count--;
}
}
}
static 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 count) {
int x = 0;
int y = 0;
int win = 0;
while (win < Row * Col - count)
{
printf("请输入需要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= Row && y >= 1 && y <= Col) {
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了。\n");
ShowBoard(mine, Row, Col);
break;
}
else {
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
ShowBoard(show, Row, Col);
win++;
}
}
else {
printf("坐标非法,请重新输入\n");
}
}
if (win == Row * Col - Easy_count)
{
printf("恭喜你,挑战成功!");
ShowBoard(mine, Row, Col);
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("********************\n");
printf("*** 1.easy play ***\n");
printf("*** 2.hard play ***\n");
printf("***** 0.exit *****\n");
printf("********************\n");
}
void game(int input)
{
char mine[Rows][Cols];
char show[Rows][Cols];
//初始化棋盘
InitBoard(mine, Rows, Cols,'0');
InitBoard(show, Rows, Cols,'*');
//打印棋盘
ShowBoard(show, Row, Col);
int count = choice(input);
//布置雷
SetMine(mine, Row, Col,count);
//排查雷
FindMine(mine, show, Row, Col,count);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game(input);
break;
case 2:
game(input);
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
四,容易出现的问题
1,注意字符应该用单引号'括起来,不能用双引号,否则虽然不会报错,但会无法正常显示,比如这样:
2,当出现像这样一堆报错时(尤其特别多C2143,C2065),很大概率是漏了某一个函数的大花括号