c语言扫雷

1.扫雷是一款经典的游戏,用二维数组的使用去实现,加上许多函数的接口,和玩家的选择要求;

如何实现扫雷:

先创建三个文件,

1.game.c(函数接口定义)    

2.game.h   (函数声明)

3. test.c(测试游戏)

第一步宏定义棋盘及炸弹:我们设置好行数和列数之后,再在其基础上设置一个辅助棋盘既周围扩大一圈的棋盘,分别在行数及列数的基础上加二,然后我们设置炸弹数,用宏定义的好处是后期修改时方便

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define BOMBSNUM 10
#define SAFENUM ROW*COL-BOMBSNUM

初始化棋盘:(注意:如果不初始化,那么打印出来的都是随机值)

void InitBoard(char Board[ROWS][COLS], int row, int col,char ch)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			Board[i][j] = ch;
		}
	}
}

接下来放置炸弹:用字符0和1来代表炸弹可以方便我们后面计算周围的炸弹

void SetBombs(char Bombs[ROWS][COLS], int row, int col, int Bombsnum)
{
	int x, y,count=0;
	while( count < Bombsnum )
	{
		x = rand() % row+1;
		y = rand() % col+1;

		if (Bombs[x][y] != '1')
		{
			Bombs[x][y] = '1';
			count++;
		}
	}
}

使用rand函数来获取一个随机的坐标,当坐标不重复并且所处位置没有炸弹时,将炸弹存放

显示菜单:


void GameMenu()
{
	printf("*****************************************\n");
	printf("*********      1.开始游戏       *********\n");
	printf("*********      0.结束游戏       *********\n");
	printf("*****************************************\n");
}

初始化棋盘后,那么我们就显示棋盘:

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

还有一点计算炸弹的周围个数:

因为我们之前初始化时将用字符1代表有炸弹,字符0代表没有炸弹,所以在这一部我们可以利用这个规律,来计算周围的炸弹数。我们只需要让选择的位置周边的八个格子全部相加,然后减去8个字符0,即可得到整形的炸弹数,而后在主函数给其加上一个字符0将其将这个数字变为字符型的对应数字,存放与棋盘中

int BombsAround(char Bombs[ROWS][COLS], int row, int col)
{
   return Bombs[row - 1][col] + Bombs[row + 1][col] + Bombs[row][col - 1] + Bombs[row][col + 1] + Bombs[row + 1][col + 1] + Bombs[row - 1][col - 1] + Bombs[row + 1][col - 1] + Bombs[row - 1][col + 1] - 8 * '0';
}

游戏的胜负输赢条件:

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

我们只需要计算棋盘中剩余的炸弹数,当剩余炸弹数等于我们的放置炸弹数时,游戏胜利

1.当第一次为炸弹时,将炸弹移动到别的位置:

这个函数实现的方法很简单,我们只需要将那个位置的炸弹清空,再次调用SetBombs函数重新设置一个炸弹即可。

int BombsAround(char Bombs[ROWS][COLS], int row, int col)
{
   return Bombs[row - 1][col] + Bombs[row + 1][col] + Bombs[row][col - 1] + Bombs[row][col + 1] + Bombs[row + 1][col + 1] + Bombs[row - 1][col - 1] + Bombs[row + 1][col - 1] + Bombs[row - 1][col + 1] - 8 * '0';
}

2.当我们选择的位置周边不存在炸弹,同时以九宫格的方式扩撒,将周边不存在炸弹的地方展开

这个很简单我们就可以想到用递归函数来完成,我们只需要用BombsAround函数来知道这个位置是否存在炸弹,如果不存在则显示为‘ ’,如果存在则显示炸弹数。我们可以用递归的方式,当位置合法时,对他周围的八个格子进行判断,那八个格子再对他们周围的格子进行判断

void SafeArea(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col)
{
	int flag;
	flag = BombsAround(Bombs, row, col);
	if (0 == flag)
	{
		Board[row][col] = ' ';
		if (row - 1 > 0 && row + 1 <= ROW && col > 0 && col <= COL && Board[row - 1][col] == '*')
			SafeArea(Board, Bombs, row-1, col);
		if (row + 1 > 0 && row + 1 <= ROW && col > 0 && col <= COL && Board[row +1 ][col] == '*')
			SafeArea(Board, Bombs, row+1, col);
		if (row > 0 && row <= ROW && col - 1 > 0 && col - 1 <= COL && Board[row][col - 1] == '*')
			SafeArea(Board, Bombs, row, col-1);
		if (row > 0 && row <= ROW && col + 1 > 0 && col + 1 <= COL && Board[row][col + 1] == '*')
			SafeArea(Board, Bombs, row, col+1);
		if (row - 1 > 0 && row - 1 <= ROW && col - 1 > 0 && col - 1 <= COL && Board[row - 1][col - 1] == '*')
			SafeArea(Board, Bombs, row-1, col-1);
		if (row + 1 > 0 && row + 1 <= ROW && col + 1 > 0 && col + 1 <= COL && Board[row + 1][col + 1] == '*')
			SafeArea(Board, Bombs, row+1, col+1);
		if (row - 1 > 0 && row - 1 <= ROW && col + 1 > 0 && col + 1 <= COL && Board[row - 1][col + 1] == '*')
			SafeArea(Board, Bombs, row-1, col+1);
		if (row + 1 > 0 && row + 1 <= ROW && col - 1 > 0 && col - 1 <= COL && Board[row + 1][col - 1] == '*')
			SafeArea(Board, Bombs, row+1, col-1);
	}
	else
	{
		Board[row][col] = BombsAround(Bombs, row, col) + '0';
	}
}

排查炸弹:

char FindBombs(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col)
{
   int x, y,count=1;
   while(count)
   {
   	printf("请输入行和列:\n");
   	scanf("%d%d",&x,&y);
   	system("CLS");
   	if (x > 0 && x <= row && y > 0 && y <= col)
   	{
   		if (Bombs[x][y] == '1')
   		{
   			if (1 == count)
   			{
   				MoveBomb(Bombs, x, y);
   				Board[x][y] = BombsAround(Bombs, x, y) + '0';
   				if (Board[x][y] == '0')
   					Board[x][y] = ' ';
   				SafeArea(Board, Bombs, x, y);
   				count++;
   			}
   			else
   			{
   				ShowBoard(Bombs, ROW, COL);
   				return 'F';
   			}

   		}
   		else if (Board[x][y] >= '0' && Board[x][y] <= '8' && Board[x][y] != '*' && Board[x][y] != ' ')
   		{
   			printf("该坐标已被输入\n");
   		}
   		else
   		{
   			Board[x][y] = BombsAround(Bombs, x, y) + '0';
   			SafeArea(Board, Bombs, x, y);
   			count++;
   			if (WinGame(Board, ROW, COL) == BOMBSNUM)
   				return 'T';
   			ShowBoard(Board, ROW, COL);
   		}
   	}
   	else
   	{
   		printf("输入错误,请重新输入\n");
   	}
   }
}

我们需要判断输入是否合法,输入是否重复,如果错误则重新输入,当输入的位置为炸弹时,如果是第一次输入,则将炸弹移动到别的位置,如果不是第一次输入,则代表游戏失败,返回’F’。每次输入完一个位置,我们将那个位置周围的炸弹数保存到Board棋盘中,既玩家看到的棋盘,然后再使用展开函数来展开周围不必要的格子,并且用WinGame函数判断是否胜利。

void Game(char Board[ROWS][COLS],char Bombs[ROWS][COLS], int row, int col)
{
	char flag;
	InitBoard(Board, ROWS, COLS, '*');
	InitBoard(Bombs, ROWS, COLS, '0');
	SetBombs(Bombs, ROW, COL, BOMBSNUM);
	ShowBoard(Board, ROW, COL);
	printf("\n");
	ShowBoard(Bombs, ROW, COL);
	flag = FindBombs(Board, Bombs, ROW, COL);
	if (flag == 'F')
	{
		printf("该位置为炸弹,游戏结束\n");
	}
	else
	{
		printf("游戏胜利\n");
	}
}

上面想说的都说完了,完整代码如下:

game.c文件:

#include "game.h"

void GameMenu()
{
	printf("*****************************************\n");
	printf("*********      1.开始游戏       *********\n");
	printf("*********      0.结束游戏       *********\n");
	printf("*****************************************\n");
}

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

void SetBombs(char Bombs[ROWS][COLS], int row, int col, int Bombsnum)
{
	int x, y,count=0;
	while( count < Bombsnum )
	{
		x = rand() % row+1;
		y = rand() % col+1;

		if (Bombs[x][y] != '1')
		{
			Bombs[x][y] = '1';
			count++;
		}
	}
}
//放置炸弹

void ShowBoard(char Board[ROWS][COLS], int row, int col)
{
	int i, j;
	printf(" ");
	for (i = 0; i < row+1; i++)
	{
		printf("%d   ",i);
	}
	printf("\n");
	for (i = 0; i < row; i++)
	{
		if (0 == i)
			printf("   |");
		else
			printf("|");
		printf("---");
	}
	printf("|\n");
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (0 == j)
			{
				printf(" ");
				printf("%d ", i + 1);
				printf("|");
			}
			printf(" %c |", Board[i+1][j+1]);
		}
		printf("\n");
		for (j = 0; j < col; j++)
		{
			if ( 0 == j )
				printf("   |");
			printf("---|");
		}
		printf("\n");
	}
}
//界面

int BombsAround(char Bombs[ROWS][COLS], int row, int col)
{
	return Bombs[row - 1][col] + Bombs[row + 1][col] + Bombs[row][col - 1] + Bombs[row][col + 1] + Bombs[row + 1][col + 1] + Bombs[row - 1][col - 1] + Bombs[row + 1][col - 1] + Bombs[row - 1][col + 1] - 8 * '0';
}
//算出周围的炸弹

void MoveBomb(char Bombs[ROWS][COLS], int row, int col)
{
	Bombs[row][col] = '0';
	SetBombs(Bombs, ROW, COL, 1);
}
//防止玩家第一次选择时遇到炸弹,将炸弹移动到别的位置

void SafeArea(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col)
{
	int flag;
	flag = BombsAround(Bombs, row, col);
	if (0 == flag)
	{
		Board[row][col] = ' ';
		if (row - 1 > 0 && row + 1 <= ROW && col > 0 && col <= COL && Board[row - 1][col] == '*')
			SafeArea(Board, Bombs, row-1, col);
		if (row + 1 > 0 && row + 1 <= ROW && col > 0 && col <= COL && Board[row +1 ][col] == '*')
			SafeArea(Board, Bombs, row+1, col);
		if (row > 0 && row <= ROW && col - 1 > 0 && col - 1 <= COL && Board[row][col - 1] == '*')
			SafeArea(Board, Bombs, row, col-1);
		if (row > 0 && row <= ROW && col + 1 > 0 && col + 1 <= COL && Board[row][col + 1] == '*')
			SafeArea(Board, Bombs, row, col+1);
		if (row - 1 > 0 && row - 1 <= ROW && col - 1 > 0 && col - 1 <= COL && Board[row - 1][col - 1] == '*')
			SafeArea(Board, Bombs, row-1, col-1);
		if (row + 1 > 0 && row + 1 <= ROW && col + 1 > 0 && col + 1 <= COL && Board[row + 1][col + 1] == '*')
			SafeArea(Board, Bombs, row+1, col+1);
		if (row - 1 > 0 && row - 1 <= ROW && col + 1 > 0 && col + 1 <= COL && Board[row - 1][col + 1] == '*')
			SafeArea(Board, Bombs, row-1, col+1);
		if (row + 1 > 0 && row + 1 <= ROW && col - 1 > 0 && col - 1 <= COL && Board[row + 1][col - 1] == '*')
			SafeArea(Board, Bombs, row+1, col-1);
	}
	else
	{
		Board[row][col] = BombsAround(Bombs, row, col) + '0';
	}
}

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

char FindBombs(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col)
{
	int x, y,count=1;
	while(count)
	{
		printf("请输入行和列:\n");
		scanf("%d%d",&x,&y);
		system("CLS");
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (Bombs[x][y] == '1')
			{
				if (1 == count)
				{
					MoveBomb(Bombs, x, y);
					Board[x][y] = BombsAround(Bombs, x, y) + '0';
					SafeArea(Board, Bombs, x, y);
					count++;
				}
				else
				{
					ShowBoard(Bombs, ROW, COL);
					return 'F';
				}

			}
			else if (Board[x][y] >= '0' && Board[x][y] <= '8' && Board[x][y] != '*' && Board[x][y] != ' ')
			{
				printf("该坐标已被输入\n");
			}
			else
			{
				Board[x][y] = BombsAround(Bombs, x, y) + '0';
				SafeArea(Board, Bombs, x, y);
				count++;
				if (WinGame(Board, ROW, COL) == BOMBSNUM)
					return 'T';
				ShowBoard(Board, ROW, COL);
			}
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}
//排查炸弹

void Game(char Board[ROWS][COLS],char Bombs[ROWS][COLS], int row, int col)
{
	char flag;
	InitBoard(Board, ROWS, COLS, '*');
	InitBoard(Bombs, ROWS, COLS, '0');
	SetBombs(Bombs, ROW, COL, BOMBSNUM);
	ShowBoard(Board, ROW, COL);
	printf("\n");
	flag = FindBombs(Board, Bombs, ROW, COL);
	if (flag == 'F')
	{
		printf("该位置为炸弹,游戏结束\n");
	}
	else
	{
		printf("游戏胜利\n");
	}
}

test.c文件:


#include "game.h"

int main()
{
	int n;
	char board[ROWS][COLS] = { 0 };
	char bombs[ROWS][COLS] = { 0 };
	srand((int)time(NULL));
	do
	{
		GameMenu();
		printf("请输入您的选择:\n");
		scanf("%d", &n);

		switch (n)
		{
		case 1:
			Game(board, bombs, ROWS, COLS);
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	}while (n);

	return 0;
}

game.h文件:

#define _CRT_SECURE_NO_WARNINGS
#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

#define BOMBSNUM 10


void GameMenu();

void InitBoard(char Board[ROWS][COLS], int row, int col, char ch);

void SetBombs(char Bombs[ROWS][COLS], int row, int col, int Bombsnum);

void ShowBoard(char Board[ROWS][COLS], int row, int col);

int BombsAround(char Bombs[ROWS][COLS], int row, int col);

char FindBombs(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col);

void Game(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col);

void MoveBomb(char Bombs[ROWS][COLS], int row, int col);

void OpenMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y);

void SafeArea(char Board[ROWS][COLS], char Bombs[ROWS][COLS], int row, int col);

扫雷到此设计结束了,感谢您的阅读!!!如果内容对您有所帮助,记得给我点赞,关注,收藏,谢谢!后续持续更新!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值