C语言扫雷游戏

游戏规则:先随机点开任意方格,如果爆炸,则扫雷失败游戏结束,如果没有爆炸,会出现一个数字,这个数字代表的意思是以它为中心的8个格子中所有雷的个数,一般围在一堆数字中间的有可能是雷.等打开所有非雷区,你就赢啦!在这里插入图片描述

首先依旧是写好代码框架,一个好的代码框架可以让你的思维更加清晰。
int main()
{
	int quit = 0;
	do{
		int select = 0;
		Menu();
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Game();
			printf("当前游戏结束,是否再来一局?\n");
			break;
		case 0:
			quit = 1;
			printf("即将退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (!quit);
	system("pause");
	return 0;
}
然后是游戏需要实现的基本功能
void Menu();//游戏菜单
void Game();//游戏主要函数
void InitBoard(char baord[][COL], int row, int col, char elem);//初始化棋盘
void SetMine(char mine[][COL], int row, int col); //设置雷
void ShowBoard(char baord[][COL], int row, int col); //展示棋盘
char GetNum(char mine[][COL], int x, int y);//计算雷的个数

这里有需要注意的地方:
为了方便我们设置了两个棋盘,一个是提供给玩家看的棋盘,一个是用于埋雷的棋盘。
在每扫一次雷之后,我们会对周围八个格子雷的数量进行计算,然后展示出来,那么,这种情况下,对于边缘的格子甚至四个角都不好计数,所以实际上我们的埋雷棋盘会比实际展示给玩家的棋盘要多两列两行,使得边缘与角的计算周围雷个数的方法与其余地方是一样的,这也降低了设计GetNum函数的困难。

这里是设置雷的函数

减2是因为设置的棋盘会比实际展示的棋盘多两行两列,加1是因为两行两列是分别分布在实际棋盘的四周的。

void SetMine(char mine[][COL], int row, int col)
{
	int n = NUM;
	while (n)
	{
		int x = rand() % (row - 2) + 1;
		int y = rand() % (col - 2) + 1;
		if (mine[x][y] == '1')
		{
			continue;
		}
		mine[x][y] = '1';//设置有雷处为字符'1',无雷处为字符'0'
		n--;
	}
}
接下来是棋盘展示函数

在此做一个小贴士,因为棋盘的展示是一个游戏的门面,所以代码实际展示出来的画面要很合适,但是全文代码太多,可以在对棋盘定义及初始化之后测试一下ShowBoard函数,在确定没问题之后再进行之后的编写。

void ShowBoard(char board[][COL], int row, int col)
{
	int i = 0;
	printf("  |");
	for (i = 1; i <= col - 2; i++)
	{
		printf("%2d |", i);
	}
	printf("\n");
	for (i = 1; i <= row - 2; i++)
	{
		printf("%3s", "----");
	}
	printf("----\n");
	for (i = 1; i <= row - 2; i++)
	{
		printf(" %d|", i);
		int j = 0;
		for (j = 1; j <= col - 2; j++)
		{
			printf(" %c |", board[i][j]);
		}
		printf("\n");
		for (j = 1; j <= col - 2; j++)
		{
			printf("%3s", "----");
		}
		printf("----\n");
	}
}

下面是C语言扫雷游戏的完整代码
头文件mine.h

#ifndef _MINE_H_
#define _MINE_H_

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>

#pragma warning(disable:4996)

//定义以下三个宏是为了扫雷游戏的棋盘大小和雷的个数可以很轻松的更改
#define ROW 10
#define COL 10
#define NUM 20

void Menu();
void Game();
void InitBoard(char baord[][COL], int row, int col, char elem);
void SetMine(char mine[][COL], int row, int col); 
void ShowBoard(char baord[][COL], int row, int col); 
char GetNum(char mine[][COL], int x, int y);

#endif

源文件的函数部分mine.c

#include "mine.h"

void Menu()
{
	printf("##########################\n");
	printf("##   欢迎进入扫雷游戏   ##\n");
	printf("######    1.PLAY    ######\n");
	printf("######    0.EXIT    ######\n");
	printf("##########################\n");
	printf("请选择:>\n");
}

void InitBoard(char board[][COL], int row, int col, char elem)
{
	int i = 0;
	for (i = 0; i <row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = elem;
		}
	}
}

void SetMine(char mine[][COL], int row, int col)
{
	int n = NUM;
	while (n)
	{
		int x = rand() % (row - 2) + 1;
		int y = rand() % (col - 2) + 1;
		if (mine[x][y] == '1')
		{
			continue;
		}
		mine[x][y] = '1';//设置有雷处为字符'1',无雷处为字符'0'
		n--;
	}
}

//展示雷的位置的图要比实际排雷的图大一圈
void ShowBoard(char board[][COL], int row, int col)
{
	int i = 0;
	printf("  |");
	for (i = 1; i <= col - 2; i++)
	{
		printf("%2d |", i);
	}
	printf("\n");
	for (i = 1; i <= row - 2; i++)
	{
		printf("%3s", "----");
	}
	printf("----\n");
	for (i = 1; i <= row - 2; i++)
	{
		printf(" %d|", i);
		int j = 0;
		for (j = 1; j <= col - 2; j++)
		{
			printf(" %c |", board[i][j]);
		}
		printf("\n");
		for (j = 1; j <= col - 2; j++)
		{
			printf("%3s", "----");
		}
		printf("----\n");
	}
}

char GetNum(char mine[][COL], 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] - 7 * '0';
}

void Game()
{
	srand((unsigned long)time(NULL));
	char board[ROW][COL];
	char mine[ROW][COL];
	InitBoard(board, ROW, COL, '*');
	InitBoard(mine, ROW, COL, '0');
	SetMine(mine, ROW, COL);

	int count = (ROW - 2) * (COL - 2) - NUM;
	do{
		system("cls");
		int x = 0;
		int y = 0;
		ShowBoard(board, ROW, COL);
		printf("请输入你要扫雷的位置:>");
		scanf("%d %d", &x, &y);
		if (x < 1 || x > ROW - 2 || y < 1 || y >  COL - 2)
		{
			printf("你输入的位置有误");
			Sleep(1000);
			continue;
		}
		if (board[x][y] != '*')
		{
			printf("你输入的位置已经被扫过");
			Sleep(1000);
			continue;
		}
		if (mine[x][y] == '0')
		{
			count--;
			char num = GetNum(mine, x, y);
			board[x][y] = num;
		}
		else
		{
			printf("你输入的位置(%d,%d)有雷\n",x,y);
			break;
		}
	} while (count > 0);
	char *result = NULL;
	if (count > 0)
	{
		result = "你被炸死了,游戏结束!";
	}
	else
	{
		result = "扫雷结束,恭喜你成功完成扫雷!";
	}
	printf("%s\n",result);
	ShowBoard(mine, ROW, COL);
}

源文件的主函数部分main.c

#include "mine.h"

int main()
{
	int quit = 0;
	do{
		int select = 0;
		Menu();
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Game();
			printf("当前游戏结束,是否再来一局?\n");
			break;
		case 0:
			quit = 1;
			printf("即将退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (!quit);
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值