c语言------扫雷游戏

扫雷游戏的玩法:

首先玩家按1:开始游戏;

其次玩家通过排查,输入一个非雷点坐标,直至排查完所有的非雷点坐标,在其过程中如果有一个是雷点,则游戏失败。

对于扫雷游戏的实现,我们这里采用分文件编写,这样做的使其功能责任划分,调试也更加方便;

game.h-------函数的声明

game.c--------游戏各个功能函数进行编写

test_SL.c------主函数

基本布局

1.play:开始游戏

0.exit:退出游戏

其他数字:输入不合法,重新输入

菜单:

采用switch语句对于每个部分进行编写:

    int a;
    do
	{
		menu();
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入不合法,请重新输入!\n");
			break;
		}
	} while (a);

1、开始游戏

布置棋盘:

用数组来模拟棋盘,设置一个9*9的棋盘,判断是否存在数组越界现象

1
1
1
1

若在棋盘边界位置:在计算其周围雷的个数时会出现数组越界,解决这个问题开一个11*11的数组即可。

11
1
1
11
1
11

#define row 9
#define col 9

#define rows row+2
#define cols col+2

对于后续如果需要改变行列的数量,只需要在此处修改即可。

解决完数组越界问题后对棋盘进行初始化:

这里设置两个棋盘分别是mine[][](布置雷),show[][](排查雷)

对于mine[][]棋盘:最先初始化为‘0’,表示没有雷,游戏开始后系统自动随机生成一定数量的雷,其对应的坐标的值则变成了字符‘1’。

对于show[][]棋盘:初始化为字符‘*’,通过玩家输入一个合理化的坐标(x,y),系统将对比该点坐标在mine[][]中是否为雷点,如果是,则玩家游戏失败;如果不是,将在show[][]棋盘中更新该点坐标为周围的雷的数量。

void initborad(char arr[rows][cols], int r, int c,char set)
{
	int i, j;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			arr[i][j] = set;//其中对于mine[][]初始化‘0’,show[][]初始化‘*’
		}
	}
}//mine[][]中‘0’表示不是雷点,‘1’表示是雷点;

打印棋盘

void disborad(char arr[rows][cols], int r, int c)
{
	int i, j;
	for (int i = 0; i <= r; i++)
		printf("%d ", i);
	printf("\n");

	for (i = 1; i <= r; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= c; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

布置雷

随机产生x,y值如在mine[][]棋盘中该点为‘0’,则将该点设置为雷点,(x,y)坐标变为字符‘1’;

	int count = 10;
	while (count)
	{
		int x = rand() % 9 + 1;//1~9
		int y = rand() % 9 + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}

其中随机数的产生:

采用rand()函数生成随机数;(范围:0—RAND_MAX(32767))

但是rand生成的随机数是伪随机数--->种子没有变化

解决这个问题:采用srand-->初始化种子的随机值

即:srand((unsigned int)time(NULL));//返回的时间戳

(不能每次生成随机数时都要设置一个种子,设置一次即可,否则产生的随机数相差不大甚至相等)

这里还需要添加两个头文件:

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

布置完雷后:

排查雷

首先玩家先输入一个合理的坐标,如果是雷点,则游戏失败;如若不是则在该点显示其周围的雷点数;依次,直至排查出所有的非雷点,扫雷成功。

void findmine(char mine[rows][cols], char show[rows][cols], int r, int c)
{
	int x, y;
	int win = 0;
	while(win<row*col-10)
	{
		printf("请输入要排查的坐标:\n");
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾你被炸死了\n");
				break;
			}
			else
			{
				int n = getminecount(mine, x, y);//获取周围的雷点
				show[x][y] = n + '0';
				disborad(show, row, col);
				win++;
			}
		}
		else
		{
			printf("坐标错误!请重新输入\n");
		}
	}
	if (win == row * col - 10)
	{
		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] + mine[x][y + 1] +
		mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 9 * '0';
}

也可以写出:
static 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] + mine[x][y + 1] +
		mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 9 * '0';
}//加上static后将该函数设置为静态函数,只在此文件中可以访问。

2、退出游戏

直接按0即可退出游戏

3、完整代码

test_SL.c
#define _CRT_SECURE_NO_WARNINGS 1


#include"game.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];
	
	//初始化棋盘
	initborad(mine, rows, cols,'0');
	initborad(show, rows, cols,'*');
	//打印棋盘
	//disborad(show, row, col);
	//disborad(mine, row, col);
	//布置雷
	setmine(mine, row, col);
	disborad(mine, row, col);
	//排查雷
	findmine(mine, show, row, col);
}

int main()
{
	int a;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入不合法,请重新输入!\n");
			break;
		}
	} while (a);

}


game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

void initborad(char arr[rows][cols], int r, int c,char set)
{
	int i, j;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			arr[i][j] = set;
		}
	}
}

void disborad(char arr[rows][cols], int r, int c)
{
	int i, j;
	for (int i = 0; i <= r; i++)
		printf("%d ", i);
	printf("\n");

	for (i = 1; i <= r; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= c; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

void setmine(char arr[rows][cols], int r, int c)
{
	int count = 10;
	while (count)
	{
		int x = rand() % 9 + 1;//1~9
		int y = rand() % 9 + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}

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

void findmine(char mine[rows][cols], char show[rows][cols], int r, int c)
{
	int x, y;
	int win = 0;
	while(win<row*col-10)
	{
		printf("请输入要排查的坐标:\n");
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾你被炸死了\n");
				break;
			}
			else
			{
				int n = getminecount(mine, x, y);
				show[x][y] = n + '0';
				disborad(show, row, col);
				win++;
			}
		}
		else
		{
			printf("坐标错误!请重新输入\n");
		}
	}
	if (win == row * col - 10)
	{
		printf("排雷成功!\n");
	}
}


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
//初始化棋盘
void initborad(char arr[rows][cols], int r, int c,char set); 
//打印棋盘
void disborad(char arr[rows][cols], int r, int c);

//布置雷
void setmine(char arr[rows][cols], int r, int c);

//排查雷
void findmine(char mine[rows][cols], char show[rows][cols], int r, int c);

以上就是扫雷游戏的基本思路和代码,希望有所帮助。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值