扫雷游戏

扫雷游戏:格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
一.要求

1.第一次扫雷的时候,要确保扫不到雷子。
2.扫到雷的时候,游戏退出。
3.玩家看到的是10*10的背景大小,雷子的个数是20。

二.整体思路

1.设两个表,一张雷表,一张玩家表,大小都为12X12。但显示的时候都是显示中间的10X10部分。
设置大小为12X12的原因是,为了方便计算显示的10X10边框上的附近有雷个数。
'1’表示该位置是雷,'0’表示该位置没雷。

12X12雷表 边框都为’0’。
下图为简略的雷表(蓝色为显示部分):
在这里插入图片描述
下图为相应玩家表(蓝色是显示部分):
在这里插入图片描述
在图中黄色的是玩家排雷的位置,在玩家表中显示周围雷的个数。

2.埋雷
使用随机数生成雷的座标x,y;总共要生成雷的个数为20个。
3.玩家扫雷
玩家输入座标进行扫雷。
要避免玩家第一次扫到雷的情况发生,我们可以这么做:雷埋完毕,找到一个非雷的座标保存起来(n_x , n_y),如果玩家第一次扫到雷了,座标是(x,y),那么交换座标(n_x , n_y)和座标(x,y)里存的内容。雷会被交换掉,而且也不会改变雷的个数。
4.玩家表上显示该位置附近雷的个数
5.显示玩家表
6.如果玩家输了,要提醒玩家,并且要显示出相应雷的表

三.实现代码

头文件 mine.h
函数的初始化和宏定义。

#ifndef __MINE__
#define __MINE__
#include<stdio.h>
#include<windows.h>
#include<string.h>//要用到给数组初始化的memset函数
#include<time.h>//要用到随机数

#pragma warning (disable:4996)

#define ROW 12
#define COL 12
#define MINES 20
//埋雷
void Set_mine(char board[][COL], int row, int col, int *x_p, int *y_p);
//打印表
void Show_Board(char board[][COL], int row, int col);
//该位置附近雷的个数
int GetCount(char board[][COL], int x, int y);

#endif

主函数 main.c
实现菜单的打印,选择开始游戏和退出游戏。

#include"mine.h"

void menu()//打印菜单
{
	printf("##########################\n");
	printf("######欢迎来到扫雷游戏#####\n");
	printf("##########################\n");
	printf("####1.play#####2.exit#####\n");
	printf("##########################\n");
	printf("请选择>>> ");
}
int main()
{
	int quit = 0;   
	while (!quit)
	{
		menu();                //打印菜单
		int select = 0;
		scanf("%d", &select);
		switch (select)
		{
		case 1:				  //开始游戏
			game();
			break;
		case 2:               //退出游戏
			quit = 1;
			break;
		default:              //输入有误
			printf("请重新选择!\n");
			break;
		}
	}
	printf("欢迎下次来玩,再见。\n");
	system("pause");
	return;
}

子函数mine.c
实现游戏埋雷功能,打印功能,计算座标附近雷的个数的功能

#include"mine.h"
//埋雷
void Set_mine(char board[][COL],int row, int col,int *x_p,int *y_p)
{
	int count = MINES;
	while (count>0)
	{
		int x = rand()%10+1;
		int y = rand()%10+1;
		if (board[x][y] == '0')
		{
			count--;
			board[x][y] ='1';
		}
		int i = 1;
		for (; i <= 10; i++)
		{
			int j = 1;
			for (; j <= 10; j++)
			{
				if (board[i][j] == '0')
				{
					*x_p = i;
					*x_p = j;
				}
				break;
			}
		}
	}
}
//打印表
void Show_Board(char board[][COL], int row, int col)
{
	int i = 1;
	printf("    ");
	for (; i <=10; i++)
	{
		printf("  %d  ", i);
	}
	printf("\n");
	for (i = 1; i <=10; i++)
	{
		printf("-----");
	}
	printf("---\n");
	for (i = 1; i <=10; i++)
	{
		printf(" %d | ", i);
		int j = 1;
		for (; j <=10; j++)
		{
			printf(" %c | ",board[i][j]);
		}
		printf("\n");
		int k;
		for (k = 1; k <=10; k++)
		{
			printf("-----");
		}
		printf("---\n");
	}
}
//座标<x,y>附近雷的个数
int GetCount(char board[][COL], int x,int y)
{
	int num = (board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \
		board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + \
		board[x + 1][y] + board[x + 1][y + 1])-('0'*8);
	return num;
}
void game()
{
	srand((unsigned long)time(NULL));//种随机数种子
	char mine_board[ROW][COL];
	char show_board[ROW][COL];
	memset(mine_board, '0', sizeof(mine_board));//初始化雷表为'0'
	memset(show_board, '*', sizeof(show_board));//初始化玩家表为'*'
	int no_x;//雷埋完,没有雷的座标。若玩家第一次扫到雷,此座标与之交换
	int no_y;
	Set_mine(mine_board, ROW, COL,&no_x,&no_y);
	int num = 100 - MINES;
	do{
		system("cls");//清屏
		Show_Board(show_board, ROW, COL);//打印玩家表
		printf("请输入<x,y> :");
		int x = 0, y = 0;
		scanf("%d %d", &x, &y);
		if (x<1 || x>10 || y<1 || y>10)//判断玩家坐标输入是否合法
		{
			printf("座标有误!请重新输入!\n");
			continue;
		}
		if (show_board[x][y] != '*')//判断玩家输入座标是否已被排除
		{
			printf("该位置已被排除,请重新输入!\n");
			continue;
		}
		if (mine_board[x][y] == '1')
		{
			if (num == 80)//第一次扫到雷的情况
			{
				mine_board[no_x][no_y] = '1';
				mine_board[x][y] = '0';
			}
			else{
				printf("boom!\n");
				printf("game over!\n");
				Show_Board(mine_board, ROW, COL);
				printf(" 不过瘾? 要不要再来一把?\n");
				break;
			}
		}
		int count = GetCount(mine_board, x, y);//在此座标上附近雷的个数
		show_board[x][y] = count + '0';//注意:显示的是字符型
		num--;
	} while (num>0);
}

若有不足,请提醒,感谢!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值