C语言------扫雷游戏

大纲:

            本文章主要分为两个部分:

            一. 扫雷游戏分析和设计

            二. 扫雷游戏的代码实现

一. 扫雷游戏分析和设计

1)创建文件首先,我们将本项目创建2个源文件和一个头文件分别存储代码

如:test.c   game.c   game.h

在game.c  中,我们将敲出扫雷程序的主体代码。

在test.c 中,我们将敲出扫雷程序中所用的函数。

在game.h 中, 我们将列出本项目中所用函数的声明,及头文件。

通过这三个文件,便于以后我们对项扫雷游戏的更改,同时便于别人更容易理解项目(扫雷游戏)。

2)打印菜单

说起游戏,那么我们首先需要为游戏创建一个开始游戏的界面,我们可以通过连续使用C语言中“printf”函数的的方式来打印一个简易的界面

void menu()
{
    printf("**************************\n");
    printf("**********1.play**********\n");
    printf("**********0.exit**********\n");
    printf("**************************\n");
}

3)输入反馈

我们将运用switch函数,分三种情况对用户的输入做出反馈

void test()
{
    int input = 0;
    do
    {
        menu();

        printf("Your choice:");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("start!!!\n");
            game();
            break;
        case 0:
            printf("exit game!\n");
            break;
        default:
            printf("输入错误,请重新输入\n");
            break;
        }
    } while (input);
}

:不要忘记break!!!

4)游戏开始后的代码

我们将开始编写开始游戏的代码:

注:为方便后期更改,我们可以通过定义两个变量来确定棋盘的大小

即:

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2 
#define EASY_COUNT 10  //可改变数字来改变雷的数量

:为防止数组越界和打印行数与列数,所以创建11*11的数组

与此同时,本项目通过创建11*11的数组也可以方便后期对坐标附近雷个数的计算

1创建并初始化数组   

首先,我们可以创建两个11*11的二维数组,一个用来放置雷,一个用来呈现给玩家。

char mine[ROWS][COLS];//存放布置好的雷
char show[ROWS][COLS];//存放排查出的雷的信息

然后创建 InitBoard 函数将其初始化.

InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');

函数的具体代码

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;
		}
	}
}
2放置雷

然后我们创建 SetMine 函数在 mine 数组中随机放置10个雷:

SetMine(mine, ROW, COL);

SetMine函数源码:

void SetMine(char board[ROWS][COLS], int row, int col)
{
	//⽣成随机的坐标,布置雷
	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--;
		}
	}
}
3打印棋盘

之后便创建 DisplayBoard函数 打印棋牌展示给玩家进行游玩:

   DisplayBoard(show, ROW, COL);

 DisplayBoard函数 源码:

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");
	}
}
4排查雷并结束游戏

然后便是排查雷,通过玩家输入的坐标,将Mine数组与Show数组对比来确定

如果为雷(1)那么游戏结束,

如果不是则继续进行游戏。

为了游戏不会无穷无尽的运行下去,我们还须完成游戏结束的代码。

即:设置一个变量(win)等于0,没有雷的格子的个数,如果没扫到雷,则该变量加一,当变量为没有雷的格子的个数时,则游戏成功!

我们可以创建一个FindMine函数来实现!

FindMine(mine, show, ROW, COL);

FineMine源码:

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
			{
				//该位置不是雷,就统计这个坐标周围有⼏个雷
				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);
	}
}

上述代码中,我们还创建了一个GetMineCount函数 来告诉玩家,如果没点到雷,那么该格子附近有几个雷。

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
		mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}

:由于雷是1,所以如果扫到的不是雷,我们只需返回该坐标四周值相加的值,值是几便有几个雷。

二. 扫雷游戏的代码实现

test.c

#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 <= 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");
	}
}
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--;
		}
	}
}
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
		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
			{
				//该位置不是雷,就统计这个坐标周围有⼏个雷
				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);
	}
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

void menu()
{
    printf("**************************\n");
    printf("**********1.play**********\n");
    printf("**********0.exit**********\n");
    printf("**************************\n");
}
void game()
{
    char mine[ROWS][COLS];//存放布置好的雷
    char show[ROWS][COLS];//存放排查出的雷的信息
    //初始化棋盘
    //1. mine数组最开始是全'0'
    //2. show数组最开始是全'*'
    InitBoard(mine, ROWS, COLS, '0');
    InitBoard(show, ROWS, COLS, '*');
    //打印棋盘
    //DisplayBoard(mine, ROW, COL);
    DisplayBoard(show, ROW, COL);
    //1. 布置雷
    SetMine(mine, ROW, COL);
    //DisplayBoard(mine, ROW, COL);
    //2. 排查雷
    FindMine(mine, show, ROW, COL);
}
void test()
{
    int input = 0;
    do
    {
        menu();

        printf("Your choice:");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("start!!!\n");
            game();
            break;
        case 0:
            printf("exit game!\n");
            break;
        default:
            printf("输入错误,请重新输入\n");
            break;
        }
    } while (input);
}

int main()
{
    test();
    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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值