C 语言扫雷游戏的设计与实现

一、游戏菜单设计

void menu()
{
    printf("********************\n");
    printf("*****  1.play  *****\n");
    printf("*****  0.exit  *****\n");
    printf("********************\n");
}

该菜单提供了两个选项:

  • 输入 1 进入游戏。
  • 输入 0 退出游戏。

二、主函数设计

主函数采用 do-while 循环结构,确保游戏菜单至少显示一次,并根据用户输入执行相应的操作。

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;
}

该流程确保:

  • 用户输入 1 时,调用 game() 进入扫雷游戏。
  • 用户输入 0 时,程序退出。
  • 若输入无效,提示用户重新输入。

三、扫雷游戏的实现

1、宏定义

为方便后续修改,使用宏定义统一设置棋盘大小及雷的数量

#define ROW 9
#define COL 9

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

#define MINES 10

其中:

  • ROWCOL 代表实际可操作的棋盘大小 (9×9)。
  • ROWSCOLS 额外增加边界,防止访问越界。
  • MINES 设定游戏中雷的数量。

2、定义棋盘

游戏使用两个棋盘:

  • mine[ROWS][COLS]:存储地雷位置的棋盘。
  • show[ROWS][COLS]:展示给用户的棋盘。
char mine[ROWS][COLS];
char show[ROWS][COLS];

3、初始化棋盘

在初始化阶段:

  • mine 棋盘填充 '0',表示未放置雷。
  • show 棋盘填充 '*',用于隐藏实际内容。
void Initboard(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

 在游戏初始化时:

Initboard(mine, ROWS, COLS, '0');
Initboard(show, ROWS, COLS, '*');

4、显示棋盘

该函数用于打印当前游戏棋盘,仅展示 9×9 的可操作区域。

void Displayboard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    printf("--------扫雷--------\n");
    for (i = 0; i <= row; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    for (i = 1; i <= row; i++)
    {
        printf("%d ", i);
        for (j = 1; j <= col; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
}

5、随机布雷

通过 rand() 生成随机坐标,并在 mine 棋盘中标记地雷 ('1')。

void Setmine(char board[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = MINES;
	while (count)
	{
		x = rand() % row+1;
		y = rand() % col+1;
		if (board[x][y] == '0') 
		{
			board[x][y] = '1';
			count--;
		}
	}
	
}

该函数确保:

  • 随机选择 9×9 区域内的坐标。
  • 若该位置无雷,则放置雷并减少 count,直至 count == 0

6、计算周围雷的数量

计算某一坐标周围 8 个方向上的地雷数量,并返回该值。

int Nummine(char mineboard[ROWS][COLS],int x,int y)
{
	return mineboard[x - 1][y - 1] + mineboard[x - 1][y] + mineboard[x - 1][y + 1] +
		mineboard[x][y - 1] + mineboard[x][y + 1] + mineboard[x + 1][y - 1] +
		mineboard[x + 1][y] + mineboard[x + 1][y + 1] - 8 * '0';
}

 7、玩家操作

玩家输入坐标:

  • 若坐标是雷,游戏结束。
  • 若非雷,显示该位置周围的雷数。
  • 若重复输入,提示错误。
void Findmine(char mineboard[ROWS][COLS], char showboard[ROWS][COLS],int row,int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<(row*col- MINES))
	{
		printf("请输入坐标:> ");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mineboard[x][y] == '1')
			{
				printf("您被炸死了!\n");
				Displayboard(mineboard, ROW, COL);
				break;
			}
			else
			{
				if (showboard[x][y] == '*')
				{
					int r = Nummine(mineboard, x, y);
					showboard[x][y] = r + '0';
					Displayboard(showboard, ROW, COL);
					win++;
				}
				else
				{
					printf("输入重复!\n");
				}
			}
		}	
		else
		{
			printf("输入错误!\n");
		}
	}
	if (win == row * col - MINES)
	{
		printf("您赢啦!\n");
	}
}

四、程序

test.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 mine[ROWS][COLS];
	char show[ROWS][COLS];

	Initboard(mine, ROWS, COLS, '0');
	Initboard(show, ROWS, COLS, '*');

	//Displayboard(mine, ROW, COL);
	//Displayboard(show, ROW, COL);

	Setmine(mine, ROW, COL);
	//Displayboard(mine, ROW, COL);
	Displayboard(show, ROW, COL);
	Findmine(mine, show,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;
}

game.h

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 9
#define COL 9

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

#define MINES 10

void Initboard(char board[ROWS][COLS], int rows, int cols, char set);
void Displayboard(char board[ROWS][COLS], int rows, int cols);
void Setmine(char board[ROWS][COLS], int row, int col);
void Findmine(char mineboard[ROWS][COLS], char showboard[ROWS][COLS], int row, int col);

 game.c

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void Initboard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("--------扫雷--------\n");
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}
void Setmine(char board[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = MINES;
	while (count)
	{
		x = rand() % row+1;
		y = rand() % col+1;
		if (board[x][y] == '0') 
		{
			board[x][y] = '1';
			count--;
		}
	}
	
}
int Nummine(char mineboard[ROWS][COLS],int x,int y)
{
	return mineboard[x - 1][y - 1] + mineboard[x - 1][y] + mineboard[x - 1][y + 1] +
		mineboard[x][y - 1] + mineboard[x][y + 1] + mineboard[x + 1][y - 1] +
		mineboard[x + 1][y] + mineboard[x + 1][y + 1] - 8 * '0';
}
void Findmine(char mineboard[ROWS][COLS], char showboard[ROWS][COLS],int row,int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<(row*col- MINES))
	{
		printf("请输入坐标:> ");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mineboard[x][y] == '1')
			{
				printf("您被炸死了!\n");
				Displayboard(mineboard, ROW, COL);
				break;
			}
			else
			{
				if (showboard[x][y] == '*')
				{
					int r = Nummine(mineboard, x, y);
					showboard[x][y] = r + '0';
					Displayboard(showboard, ROW, COL);
					win++;
				}
				else
				{
					printf("输入重复!\n");
				}
			}
		}	
		else
		{
			printf("输入错误!\n");
		}
	}
	if (win == row * col - MINES)
	{
		printf("您赢啦!\n");
	}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值