扫雷简易版

思路:

1.创建两个棋盘,一个为雷分布棋盘mine,一个为展示给玩家的棋盘show,在mine棋盘上设置雷的个数,show上展示周围雷的个数。为了避免越界,mine棋盘的行和列比show多2。ROW,COL为mine的行和列,Row,Col为show的行和列。

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
#include"stdio.h"
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<stdbool.h>
#include<limits.h>
#define ROW 12//行数
#define COL 12//列数
#define Row ROW-2
#define Col COL-2
void printmine(char mine[ROW][COL], int row, int col);
void printshow(char show[Row][Col], int row, int col);
void initmine(char mine[ROW][COL], int row, int col);
void initshow(char show[Row][Col], int row, int col);
void placemine(char board[ROW][COL],int row,int col,int num);
int*  player(char mine[ROW][COL], char show[Row][Col], int row, int col);
int judgement(char mine[ROW][COL], char show[Row][Col], int row, int col);
void changemine(char mine[ROW][COL],  int row, int col, int x, int y);
void compute_new(char mine[ROW][COL], char show[Row][Col], int row, int col, int x, int y);
void initvisted();

2.打印棋盘。printmine,printshow两个函数,二维数组传参加上行和列。

void printmine(char mine[ROW][COL], int row, int col)
{
	printf("   ");
	for (int y = 0; y < col - 2; y++) {
		printf("%d ", y);
	}
	printf("\n");
	for (int x = 1; x < row - 1; x++)
	{
		printf("%2d ", x - 1);
		for (int y = 1; y < col - 1; y++)
		{
			printf("%c ", mine[x][y]);
		}
		printf("\n");
	}
}
void printshow(char show[Row][Col], int row, int col)
{
	printf("  ");
	for (int y = 0; y < col; y++) {
		printf("%d ", y);
	}
	printf("\n");
	for (int x = 0; x < row; x++)
	{
		printf("%d ", x);
		for (int y = 0; y < col; y++)
		{
			printf("%c ", show[x][y]);
		}
		printf("\n");
	}
}

3.初始化棋盘。mine棋盘字符'0'不为雷,'1'为雷。show棋盘'*'为未排雷坐标。

void initmine(char mine[ROW][COL], int row, int col)
{
	for (int x = 0; x < row; x++)
	{
		for (int y = 0; y < col; y++)
		{
			mine[x][y] = '0';
		}
	}
}
void initshow(char show[Row][Col], int row, int col)
{
	for (int x = 0; x < row; x++)
	{
		for (int y = 0; y < col; y++)
		{
			show[x][y] = '*';
		}
	}
}

4.给mine棋盘设置雷。使用随机数,rand()函数,加上随机数种子,srand((unsigned int)time(NULL)),避免重复放置雷,需要判断,if (board[x][y] != '1')。

void placemine(char board[ROW][COL], int row, int col,int num)
{
	int i = 0;
	while (i < num)
	{
		int x = rand() % (row)+1;
		int y = rand() % (col)+1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			i++;
		}
	}
}

5.玩家开始排雷。为了避免游戏提前结束,第一个应该不是雷。changemine函数

void changemine(char mine[ROW][COL], int row, int col, int x, int y)
{
	int xm = x + 1;
	int ym = y + 1;
	while (1)
	{
		int x0 = rand() % (row)+1;
		int y0 = rand() % (col)+1;
		if (mine[x0][y0] != '1' && x0 != xm && y0 != ym)
		{
			mine[x0][y0] = '1';
			break;
		}
	}
	mine[x + 1][y + 1] = '0';
}

6.玩家输入坐标后需要判断这个位置是否为雷,是则游戏结束,否则判断这个位置周围雷个数,(使用函数compute_new,)并不断扩大范围(使用递归算法),上下左右,直到那个位置周围有雷。同时为了避免重复判断,使用visited数组,某个坐标未被判断为0,已被判断为1。一次compute_nwe函数调用后和玩家下次输入坐标时,visited需要重新置0,使用initvisited函数。玩家输入坐标,函数player返回输入的坐标以及这个位置是否为雷,是返回0,否为1;如果越界,判断后重新输入。

int* player(char mine[ROW][COL], char show[Row][Col], int row, int col)
{
	int* data = (int*)malloc(sizeof(int) * 3);
	printf("请输入坐标\n");
	while (1) {
		int x, y;
		scanf("%d %d", &x, &y);
		if (mine[x + 1][y + 1] == '1')
		{
			data[0] = 0;
			data[1] = x;
			data[2] = y;
			return data;
		}
		else if (x < 0 || x >= row || y < 0 || y >= col)
		{
			printf("坐标非法,请重新输入\n");

		}
		else if (mine[x + 1][y + 1] == '0')
		{
			data[0] = 1;
			data[1] = x;
			data[2] = y;
			return data;
		}
	}
}
void compute_new(char mine[ROW][COL], char show[Row][Col], int row, int col, int x, int y)
{
	if (x >= 0 && y >= 0 && x < row && y < col && visited[x][y] == 0) {
		int sum = mine[x - 1 + 1][y - 1 + 1] - '0'
			+ mine[x - 1 + 1][y + 1] - '0'
			+ mine[x - 1 + 1][y + 1 + 1] - '0'
			+ mine[x + 1][y - 1 + 1] - '0'
			+ mine[x + 1][y + 1 + 1] - '0'
			+ mine[x + 1 + 1][y - 1 + 1] - '0'
			+ mine[x + 1 + 1][y + 1] - '0'
			+ mine[x + 1 + 1][y + 1 + 1] - '0';
		show[x][y] = sum + '0';
		visited[x][y] = 1;
		if (show[x][y] == '0') {
			if (mine[x - 1 + 1][y + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x - 1, y);
			}
			if (mine[x + 1 + 1][y + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x + 1, y);
			}
			if (mine[x + 1][y - 1 + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x, y - 1);
			}
			if (mine[x + 1][y + 1 + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x, y + 1);
			}
			if (mine[x - 1 + 1][y - 1 + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x - 1, y - 1);
			}
			if (mine[x - 1 + 1][y + 1 + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x - 1, y + 1);
			}
			if (mine[x + 1 + 1][y - 1 + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x + 1, y - 1);
			}
			if (mine[x + 1 + 1][y + 1 + 1] == '0')
			{
				compute_new(mine, show, Row, Col, x + 1, y + 1);
			}
		}
	}
}
int visited[COL][ROW] = { 0 };
void initvisted() {
	for (int x = 0; x < Row; x++) {
		for (int y = 0; y < Col; y++) {
			visited[x][y] = 0;
		}
	}
}

7.每次输入坐标需要判断游戏胜利还是失败,若player函数返回的data数组的data[0]=0,则游戏失败,否则判断游戏是否胜利,使用judgement函数,返回1为胜利,否则游戏继续。

int judgement(char mine[ROW][COL], char show[Row][Col], int row, int col)
{
	int count_m = 0;
	int count_s = 0;
	for (int x = 1; x <= row; x++)
	{
		for (int y = 1; y <= col; y++)
		{
			if (mine[x][y] == '0')
			{
				count_m++;
			}
		}
	}
	for (int x = 0; x < row; x++)
	{
		for (int y = 0; y < col; y++)
		{
			if (show[x][y] != '*')
			{
				count_s++;
			}
		}
	}
	if (count_m == count_s) {
		return 1;
	}
	return 0;
}

8.调用menu函数产生游戏主界面,game函数使用循环使得玩家重复输入,并调用上述的函数。

void game();
void menu();
void menu()
{
	while (true)
	{
		printf("******************\n");
		printf("   选择1开始游戏   \n");
		printf("   选择0结束游戏   \n");
		printf("******************\n");
		int n;
		printf("请输入\n");
		scanf("%d", &n);
		if (n == 1)
		{
			printf("开始扫雷游戏\n");
			game();
		}
		else if (n == 0)
		{
			printf("结束游戏\n");
			break;
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}
void game()
{
	printf("请输入雷的个数\n");
	int num = 0;
	scanf("%d", &num);
	//地雷
	char mine[ROW][COL];
	//展示
	char show[Row][Col];
	//初始化
	initmine(mine, ROW, COL);
	initshow(show, Row, Col);
	//放置地雷
	placemine(mine, Row, Col,num);
	//打印
	//printmine(mine, ROW, COL);
	printshow(show, Row, Col);
	//输入坐标
	//第一个不是雷
	int* ty = player(mine, show, Row, Col);
	initvisted();
	if (ty[0] == 0 )
	{
		changemine(mine, Row, Col, ty[1], ty[2]);
		compute_new(mine, show, Row, Col, ty[1], ty[2]);
		printmine(mine, ROW, COL);
		//扫描展开清除一片雷区
		printshow(show, Row, Col);
	}
	else {
		compute_new(mine, show, Row, Col, ty[1], ty[2]);
		printmine(mine, ROW, COL);
		printshow(show, Row, Col);
	}
	int judge = judgement(mine, show, Row, Col);
	if (judge == 1)
	{
		printf("游戏胜利\n");
		printmine(mine, ROW, COL);
		return;
	}
	while (true)
	{
		initvisted();
		int* ret = player(mine, show, Row, Col);
		if (ret[0] == 0) {
			printf("踩到地雷,游戏失败\n");
			printmine(mine, ROW, COL);
			break;
		}
		else if (ret[0] == 1) {
			compute_new(mine, show, Row, Col, ret[1], ret[2]);
			printmine(mine, ROW, COL);
			printshow(show, Row, Col);
		}
		int judge = judgement(mine, show, Row, Col);
		if (judge == 1)
		{
			printf("游戏胜利\n");
			printmine(mine, ROW, COL);
			break;
		}
	}
}
int main() {
	srand((unsigned int)time(NULL));
	menu();
	return 0;
}

最终效果

上述便是扫雷简易版的代码,有更好的思路可以分享出来,有错误也希望能指正。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
下面是一个简单的Python实现扫雷的示例代码: ```python import random # 游戏参数 ROWS = 10 COLUMNS = 10 MINES = 10 # 方格状态 UNREVEALED = -1 MINE = -2 # 创建游戏面板 board = [[UNREVEALED for _ in range(COLUMNS)] for _ in range(ROWS)] # 随机布雷 mines = random.sample(range(ROWS * COLUMNS), MINES) for mine in mines: row, col = divmod(mine, COLUMNS) board[row][col] = MINE # 计算周围地雷数量 for row in range(ROWS): for col in range(COLUMNS): if board[row][col] == MINE: continue count = 0 for r in range(max(0, row - 1), min(row + 2, ROWS)): for c in range(max(0, col - 1), min(col + 2, COLUMNS)): if board[r][c] == MINE: count += 1 board[row][col] = count # 显示游戏面板 def print_board(): print(" ", end="") for col in range(COLUMNS): print(f"{col:2d}", end="") print() for row in range(ROWS): print(f"{row:2d} ", end="") for col in range(COLUMNS): if board[row][col] == UNREVEALED: print(" .", end="") elif board[row][col] == MINE: print(" *", end="") else: print(f" {board[row][col]}", end="") print() # 点击方格 def click(row, col): if board[row][col] == MINE: print("你踩到了地雷,游戏结束!") return False elif board[row][col] == UNREVEALED: board[row][col] = 0 for r in range(max(0, row - 1), min(row + 2, ROWS)): for c in range(max(0, col - 1), min(col + 2, COLUMNS)): if board[r][c] == UNREVEALED: click(r, c) return True else: return True # 开始游戏 print_board() while True: row = int(input("请输入行号:")) col = int(input("请输入列号:")) if not click(row, col): break print_board() ``` 这个简易版扫雷游戏使用的是命令行界面,先随机生成地雷,然后根据地雷数量计算每个方格周围的地雷数量。玩家输入行号和列号来点击方格,如果踩到地雷,则游戏结束,否则会递归地展开周围未点击过的方格,直到点击到有地雷的方格或者所有非地雷方格都被点击为止。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨落寒山意

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值