C语言实现扫雷小游戏

扫雷小游戏设计思路

1.显示游戏界面

    若我们需要一个9*9的游戏区域,我们需要设置一个11*11的面板,而只显示9*9部分。

    这是为了在统计边缘点四周雷的数目时方便。

2.布置雷

    调用rand()函数来获得放置雷的随机坐标,令该点值改为1;

    需要注意到的是,在放置雷之前我们需要判断该点是否有雷,若有雷则从新生成随机数来置雷。

3.排雷

     排雷的过程即为将没有雷的点全部显示,剩下的即为雷。


游戏运行界面:


    此处输入1或2可选择游戏难度。


    此处为游戏过程截图,当输入坐标处没有雷,会展开其周围没有雷的部分,并会显示处周围雷的个数。


    踩到雷后,会提示游戏失败,并显示出雷的位置。同时按任意键之后,可以选择开

始新游戏或退出。




main.c

#include"game.h"


//游戏初始界面
void landing()
{
	printf("\n\n\n\n\n\n\n\n\n\n\n");
	printf("                                                       扫雷游戏");
	int i = 0;
	char arr[102] = { 0 };
	printf("\n\n\n\n\n\n\n\n\n\n\n\n\n");
	for (i = i; i <= 100; i++)
	{
		arr[i] = '=';
		printf("   [%-100s][%2d%%]\r", arr, i);
		Sleep(15);
		fflush(stdout);
	}

	printf("\n\n\n                                                 ");
	system("pause");
	system("cls");
}
//游戏选择界面
void choose()
{
	printf("                             ------------------------------------------------------\n");
	printf("                            |                                                      |\n");
	printf("                            |          1.start                 2.exit              |\n");
	printf("                            |                                                      |\n");
	printf("                             ------------------------------------------------------\n");
	int i = 0;
	printf("请选择 > ");
Restart:
	scanf("%d", &i);
	switch (i)
	{
	case 1:
		game();
	case 2:
		return;
	default:
		printf("选择错误,请重新选择!\n");
		goto Restart;
	}
}

void game()
{
	int count = CHOOSE_COUNT();
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	Init(mine, ROWS, COLS, '0');
	Init(show, ROWS, COLS, '*');

	SetMine(mine,show, ROW, COL	,count);


}
int main()
{
	system("color F0");
	system("mode con:cols=115 lines=35");
	
	landing();
	choose();

	return 0;
}

game.h

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

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#define HARD_COUNT 20

void Init(char arr[ROWS][COLS], int rows, int cols, char set);//初始化
void Print(char arr[ROWS][COLS], int row, int col);//打印
void SetMine(char arr[ROWS][COLS],char show[ROWS][COLS],int row,int col,int count);//放置雷
int CHOOSE_COUNT();//选择游戏难度
GetMineCount(char arr[ROWS][COLS], int x, int y);//统计选择点周边雷的个数
void First(char arr[ROWS][COLS],int x, int y);//第一次排雷不会死
void Open(char arr[ROWS][COLS], char show[ROWS][COLS], int x, int y);//展开周围没有雷的区域
void game();

game.c

#include"game.h"

int CHOOSE_COUNT()
{
	system("cls");
	printf("                             ------------------------------------------------------\n");
	printf("                            |                                                      |\n");
	printf("                            |          1.EASY                 2.HARD               |\n");
	printf("                            |                                                      |\n");
	printf("                             ------------------------------------------------------\n");
	printf("请选择游戏难度 > ");
	int i = 0;
Restart:
	scanf("%d", &i);
	printf("\n");
	switch (i)
	{
	case 1:
		printf("选择简单模式!\n\n");
		return EASY_COUNT;
	case 2:
		printf("选择困难模式!\n\n");
		return HARD_COUNT;
	default:
		printf("选择错误,请重新选择!\n");
		goto Restart;
	}

}
void Init(char arr[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}

void Print(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("  ");
	for (i = 1; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			if (arr[i][j] == '0')
			{
				printf("  ");
			}
			else
			{
				printf("%c ", arr[i][j]);
			}
		}
		printf("\n");
	}
	printf("\n");
}

void Open(char arr[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (arr[x - 1][y - 1] == '0')
	{
		show[x - 1][y - 1] = GetMineCount(arr, x - 1, y - 1) +'0';//显示该坐标周围雷数
	}
	if (arr[x - 1][y] == '0')
	{
		show[x - 1][y] = GetMineCount(arr, x - 1, y) + '0';
	}
	if (arr[x - 1][y + 1] == '0')
	{
		show[x - 1][y + 1] = GetMineCount(arr, x - 1, y + 1) +  '0';
	}
	if (arr[x][y + 1] == '0')
	{
		show[x][y + 1] = GetMineCount(arr, x, y + 1) +  '0';
	}
	if (arr[x + 1][y + 1] == '0')
	{
		show[x + 1][y + 1] = GetMineCount(arr, x + 1, y + 1) +  '0';
	}
	if (arr[x + 1][y] == '0')
	{
		show[x + 1][y] = GetMineCount(arr, x + 1, y) + '0';
	}
	if (arr[x + 1][y - 1] == '0')
	{
		show[x + 1][y - 1] = GetMineCount(arr, x + 1, y - 1) +  '0';
	}
	if (arr[x][y - 1] == '0')
	{
		show[x][y - 1] = GetMineCount(arr, x , y - 1) + '0';
	}
}
void SetMine(char arr[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count)
{
	srand(time(NULL));

	int x = 0;
	int y = 0;
	int Win = 0;
	int cur = count;
	while (count)
	{

		x = rand() % row + 1;
		y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
	//Print(arr, ROW, COL);
	Print(show, ROW, COL);
	int flag = 1;//为了第一次排雷不会被炸死

	while (Win < (ROW*COL - cur))//此处cur为雷区雷的个数
	{
	start:
		printf("请输入坐标:> ");
		scanf("%d%d", &x, &y);

		if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
		{

			if (arr[x][y] == '0')
			{
				//统计四周雷的个数
				flag -= 1;
				int ret = GetMineCount(arr, x, y);
				show[x][y] = ret + '0';
				Open(arr, show, x, y);
				Print(show, ROW, COL);
				Win++;
			}
			else
			{
				if (flag == 1)
				{
					First(arr, x, y);
					flag -= 1;
					int count = 1;
					while (count)
					{
						int x1 = rand() % row + 1;
						int y1 = rand() % col + 1;
						if (arr[x1][y1] == '0')
						{
							arr[x1][y1] = '1';
							count--;
						}
					}

					int ret = GetMineCount(arr, x, y);
					show[x][y] = ret + '0';
					//Print(arr, ROW, COL);

					Open(arr, show, x, y);

					Print(arr, ROW, COL);
					Print(show, ROW, COL);
					Win++;
					goto start;
				}
				printf("\n===========================\n");
				printf("      很遗憾,踩到雷了...\n");
				printf("===========================\n\n");
				Print(arr, ROW, COL);
				system("color FC");
				system("pause");
				system("cls");
				choose();
				break;
			}
		}
		else
		{
			printf("输入错误!\n");
		}

	}
	if (Win == (ROW*COL - cur))
	{
		printf("\n===========================\n");
		printf("      恭喜你!排雷成功!   \n");
		printf("===========================\n\n");
		Print(arr, ROW, COL);
		system("color FD");

		system("pause");
		system("cls");
		choose();
	}
}



GetMineCount(char arr[ROWS][COLS], int x, int y)
{
	int count = 0;
	return count = arr[x - 1][y] + arr[x - 1][y - 1] + arr[x][y - 1] + arr[x + 1][y - 1] + \
		arr[x + 1][y] + arr[x + 1][y + 1] + arr[x][y + 1] + arr[x - 1][y + 1] - 8 * '0';
}


void First(char arr[ROWS][COLS],int x, int y)
{
	if (arr[x][y] == '1')
	{
		arr[x][y] = '0';
		x = rand() % ROW + 1;
		y = rand() % COL + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值