C语言扫雷小游戏

经过几天的努力,完成如下的c语言扫雷

主要思想是构建两个二维数组,但是构建出来的二维数组要比打印出来的大一圈,因为这样才会在后续统计雷数的时候更加方便。
然后两个二维数组,其中一个二维数组是我用来布置雷的,而另一个是展示给玩家看的。
在我的棋盘布置雷之后,让玩家在他的雷盘进行选择。

  1. 如果选择的坐标在我的棋盘是雷,则炸。
  2. 如果不是雷,则统计周围的雷数
    1.统计周围雷数,如果周围一颗雷都没有,则展开继续统计。
    2.如果周围有雷,则显示周围的雷数。

3.玩家进行一步一步的扫雷过程中,如果遇到雷,那边炸掉,重新游戏
如果没遇到雷,最后统计玩家没掀开的格子数量,如果数量是等于雷的数量,那游戏玩家获胜。

以上就是大体 的思路,下面是代码展示:
头文件game.h

#include<stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 9
#define COL 9
#define ROWS ROW +2
#define COLS COL +2
#define MINE 9

void InitBoard(char board[ROWS][COLS], int row, int col, char set);
void Display(char board[ROWS][COLS], int row, int col);
void PutMine(char board[ROWS][COLS], int row, int col);
void Saolei(char MineBoard[ROWS][COLS], int ShowBoard[ROWS][COLS], int rol, int col);
int NearMine(char mine[COLS][ROWS], int x, int y);
void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int CountBlank(char show[ROWS][COLS], int row, int col);

初始化

void InitBoard(char MineBoard[ROWS][COLS], int row, int col, char set)//初始化棋盘
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			MineBoard[i][j] = set;
		}
	}
}

打印棋盘

void Display(char board[ROWS][COLS], int row, int col)//打印棋盘
{
	{
		int i = 0;
		int j = 0;
		printf("   ");
		for (j = 0; j < col ; j++)//列序号
		{
			printf("%d   ",j+1);

		}
		printf("\n");
		for (i = 1; i <= row; i++)
		{
			printf("%d", i);//行序号
			printf(" ");
			for (j = 1; j <= col; j++)
			{
				printf(" %c ", board[i][j]);
				if (j <= col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
			printf("  ");
			for (j = 1; j <= col; j++)
			{
				if (i <= row - 1)
				{
					printf("---");
					if (j <= col - 1)
					{
						printf("|");
					}
				}
			}
			printf("\n");

		}
	}
}

放随机雷

void PutMine(char board[ROWS][COLS], int row, int col)//布置雷
{
	int x = 0;
	int y = 0;
	int count = MINE;
	while (count)
	{
		x = rand() % MINE + 1;
		y = rand() % MINE + 1;
		if (x>0 && x <= row && y>0 && y <= col && board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

统计周围雷个数

int NearMine(char mine[COLS][ROWS], 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 + 1][y] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0';
}

用递归,实现展开

void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y)
{
	int ret = NearMine(mine, x, y);
	if (ret == 0)
	{
		show[x][y] = ' ';
		if ((x - 1)>0 && (y - 1)>0 && (show[x - 1][y - 1] == '*'))
			NoMine(mine, show, x - 1, y - 1);

		if ((x - 1)>0 && (y)>0 && (show[x - 1][y] == '*'))
			NoMine(mine, show, x - 1, y);

		if ((x - 1)>0 && (y + 1)>0 && (show[x - 1][y + 1] == '*'))
			NoMine(mine, show, x - 1, y + 1);

		if ((x)>0 && (y - 1)>0 && (show[x][y - 1] == '*'))
			NoMine(mine, show, x, y - 1);

		if ((x)>0 && (y + 1)>0 && (show[x][y + 1] == '*'))
			NoMine(mine, show, x, y + 1);

		if ((x + 1)>0 && (y - 1)>0 && (show[x + 1][y - 1] == '*'))
			NoMine(mine, show, x + 1, y - 1);

		if ((x + 1)>0 && (y)>0 && (show[x + 1][y] == '*'))
			NoMine(mine, show, x + 1, y);

		if ((x + 1)>0 && (y + 1)>0 && (show[x + 1][y + 1] == '*'))
			NoMine(mine, show, x - 1, y - 1);
	}
	else
	{
		show[x][y] = ret + '0';
	}
}

统计玩家没掀开的格子个数

int CountBlank(char show[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*')
				count++;
		}
	}
	return count;
}

玩家扫雷

void Saolei(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col)
{
	int x = 0;
	int y = 0;
	int flag = 1;
	int ret = 0;
	do
	{
		printf("请输入扫雷坐标:>");
		scanf("%d%d", &x, &y);
		{
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (mine[x][y] == '0' && show[x][y] == '*')
				{
					NoMine(mine, show, x, y);
					/*Display(mine, ROW, COL);*/
					Display(show, ROW, COL);
					ret = CountBlank(show, ROW, COL);
					if (ret == MINE)
					{
						printf("你赢了\n");
						break;
					}
				}
				if (mine[x][y] == '1' && show[x][y] == '*')
				{
					show[x][y] = 'S';
					Display(show, ROW, COL);
					printf("你被炸死了,雷图如下\n");
					Display(mine, ROW, COL);
					flag = 0;
				}
			}
			else
			{
				printf("坐标非法请重新输入\n");
			}
		}
	} while (flag);
}

改装升级:第一次碰雷不炸开:设置count,每次输入坐标count便加1,在count=1时碰雷游戏继续,代码如下

void Saolei(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col)
{
	int x = 0;
	int y = 0;
	int flag = 1;
	int ret = 0;
	int count = 0;
	do
	{
		printf("请输入扫雷坐标:>");
		scanf("%d%d", &x, &y);
		count++;
		{
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (mine[x][y] == '0' && show[x][y] == '*')
				{
					NoMine(mine, show, x, y);
					/*Display(mine, ROW, COL);*/
					Display(show, ROW, COL);
					ret = CountBlank(show, ROW, COL);
					if (ret == MINE)
					{
						printf("你赢了\n");
						break;
					}
				}
				if (mine[x][y] == '1' && show[x][y] == '*'&& count == 1)
				{
					printf("你碰到雷了,第一次下子不被炸死\n");
				}
				if (mine[x][y] == '1' && show[x][y] == '*'&& count != 1)
				{
					show[x][y] = 'S';
					Display(show, ROW, COL);
					printf("你被炸死了,雷图如下\n");
					Display(mine, ROW, COL);
					flag = 0;
				}
			}
			else
			{
				printf("坐标非法请重新输入\n");
			}
		}
	} while (flag);
}

主函数text.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
	printf("**********************\n");
	printf("******1.  play********\n");
	printf("******0.  exit********\n");
	printf("**********************\n");
}
void game()
{
	char MineBoard[ROWS][COLS] = { 0 };
	char ShowBoard[ROWS][COLS] = { 0 };
	InitBoard(MineBoard, ROWS,COLS, '0');
	PutMine(MineBoard, ROW, COL);
	Display(MineBoard, ROW, COL);
	InitBoard(ShowBoard, ROWS, COLS, '*');
	Display(ShowBoard, ROW,COL);
    Saolei(MineBoard, ShowBoard, ROW, COL);
}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{case 1:
			game();
			break;
		case 0:
			printf("程序退出\n");
			break;
		default:
			printf("输入错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

实现图片
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值