【C语言】扫雷【附源码】

欢迎来到英杰社区icon-default.png?t=N7T8https://bbs.csdn.net/topics/617804998

一、扫雷游戏规则

       尽快找到雷区中的所有不是地雷的格子,而不许踩到地雷。点开的数字是几,则说明该数字旁边的8个位置中有几个雷,如果挖开的是地雷,则会输掉游戏。

二、代码思路:

  • 宏定义:

    • Row 和 Col 定义了棋盘的行数和列数。
    • Rows 和 Cols 分别定义了棋盘数组的行数和列数,多出来的两行两列是为了在棋盘的四周留出空白区域。
    • EASY 定义了简单难度下的地雷数量。
  • 函数原型:

    • InitBoard():初始化棋盘函数原型,用于在程序的其他地方实现初始化棋盘的功能。
    • DisplayBoard():打印棋盘函数原型,用于在程序的其他地方实现打印棋盘的功能。
    • SetMine():布置地雷函数原型,用于在程序的其他地方实现布置地雷的功能。
    • FindMine():找地雷函数原型,用于在程序的其他地方实现找地雷的功能。
  • 菜单函数 menu():

    •  这个函数用于显示游戏的菜单界面,提供了两个选项:开始游戏和退出游戏。 
    void menu() {
    	printf("*****************************\n");
    	printf("*****************************\n");
    	printf("***********1.play************\n");
    	printf("***********0.exit************\n");
    	printf("*****************************\n");
    	printf("*****************************\n");
    	printf("*****************************\n");
    }
  • 主函数 main():

    • 在 main() 函数中,首先声明了一个整型变量 input,用于接收用户的输入选项。
    • 进入一个 do-while 循环,这个循环会一直执行,直到用户选择退出游戏(输入 0)。
    • 在循环内部,首先调用 menu() 函数显示菜单界面,然后通过 scanf() 函数获取用户的选择,并存储在 input 变量中。
    • 使用 switch 语句根据用户的选择执行相应的操作:
      • 如果用户选择 1,则调用 game() 函数开始游戏。
      • 如果用户选择 0,则打印消息表示退出游戏。
      • 如果用户输入其他数字,则提示用户重新选择。
    • 循环条件是 input != 0,即只要用户不选择退出游戏,就会一直循环显示菜单。
    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("退出游戏");
    			break;
    		default:
    			printf("输入错误请重新输入");
    			break;
    		}
    	} while (input);
    	return 0;
    }

  • 游戏函数 game():

    • 这个函数负责实现扫雷游戏的核心逻辑。
    • 首先声明了两个二维字符数组 mine 和 show,用于存储扫雷棋盘的地雷分布情况和显示给玩家的棋盘情况。
    • 调用 InitBoard() 函数初始化两个棋盘。
    • 调用 SetMine() 函数设置地雷的位置。
    • 调用 DisplayBoard() 函数显示初始的棋盘给玩家。
    • 最后调用 FindMine() 函数开始游戏,排查地雷并更新显示给玩家的棋盘。
    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);
    	FindMine(mine, show, Row, Col);
    }
  • InitBoard() 函数:
    • 用于初始化棋盘,将棋盘的每个格子都设置为指定的字符 set。
    • 参数 rows 和 cols 分别表示棋盘的行数和列数。
    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;
    		}
    	}
    }
    • DisplayBoard() 函数:

      1. 用于显示棋盘的当前状态,包括地雷和已经排查的区域。
      2. 打印出棋盘的行号和列号,以及对应位置的字符。
      3. 参数 row 和 col 表示棋盘的行数和列数。
      void DisplayBoard(char board[Rows][Cols], int row, int col) {
      	int i = 0;
      	int j = 0;
      	printf("----------  扫雷 -----------\n");
      	for (i = 0; i <= col; 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");
      	}
      	printf("----------  扫雷 -----------\n");
      }
      • SetMine() 函数:

        1. 用于设置地雷在棋盘上的位置。
        2. 参数 row 和 col 分别表示棋盘的行数和列数。
        3. 使用 rand() 函数生成随机数,随机设置地雷的位置。
        4. count 变量表示地雷的数量,根据不同的难度(这里是简单难度)来设置地雷的数量。
        void SetMine(char board[Rows][Cols], int row, int col) {
        	int count = EASY;
        	while (count) {
        		int x = rand() % row + 1;
        		int y = rand() % col + 1;
        		if (board[x][y] == '0') {
        			board[x][y] = '1';
        			count--;
        		}
        	}
        }
        • GetMineCount() 函数:

          1. 用于统计某个位置周围地雷的数量。
          2. 参数 x 和 y 表示要统计的位置坐标。
          3. 遍历该位置周围的八个方向,统计周围地雷的数量。
          int GetMineCount(char mine[Rows][Cols], 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';
          }
          • FindMine() 函数:

            1. 实现了玩家排雷的过程。
            2. 使用 while 循环,直到排查完所有非地雷的位置或者踩到地雷为止。
            3. 每次循环提示玩家输入坐标,然后判断该位置是否有地雷。
            4. 如果踩到地雷,则游戏失败,显示所有地雷的位置。
            5. 如果没有踩到地雷,则统计周围地雷的数量,并更新显示给玩家的棋盘。
            6. 循环结束后,根据游戏是否成功来显示相应的消息
            void FindMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col) {
            	int x = 0;
            	int y = 0;
            	int win = 0;
            	while (win < Row * Col - EASY) {
            		printf("请输入坐标:");
            		scanf("%d %d", &x, &y);
            		if (x >= 1 && x <= row && y >= 1 && y <= col) {
            			if (mine[x][y] == '1') {
            				printf("炸死了\n");
            				DisplayBoard(mine, Row, Col);
            				break;
            			}
            			else//统计周围有几个地雷
            			{
            				int sum = GetMineCount(mine, x, y);
            				show[x][y] = sum + '0';//1+'0'='1'
            				DisplayBoard(show, Row, Col);
            				win++;
            			}
            		}
            		else {
            			printf("坐标错误重新输入");
            		}
            	}
            	if (win == Row * Col - EASY) {
            		printf("恭喜你排雷成功");
            		DisplayBoard(mine, Row, Col);
            	}
            }

            三、完整代码

                    test.c

                    

            #define _CRT_SECURE_NO_WARNINGS 1
            #include "game.h"
            void menu() {
            	printf("*****************************\n");
            	printf("*****************************\n");
            	printf("***********1.play************\n");
            	printf("***********0.exit************\n");
            	printf("*****************************\n");
            	printf("*****************************\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);
            	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("退出游戏");
            			break;
            		default:
            			printf("输入错误请重新输入");
            			break;
            		}
            	} while (input);
            	return 0;
            }

                    game.c

            #define _CRT_SECURE_NO_WARNINGS 1
            #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 <= col; 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");
            	}
            	printf("----------  扫雷 -----------\n");
            }
            void SetMine(char board[Rows][Cols], int row, int col) {
            	int count = EASY;
            	while (count) {
            		int x = rand() % row + 1;
            		int y = rand() % col + 1;
            		if (board[x][y] == '0') {
            			board[x][y] = '1';
            			count--;
            		}
            	}
            }
            int GetMineCount(char mine[Rows][Cols], 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 FindMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col) {
            	int x = 0;
            	int y = 0;
            	int win = 0;
            	while (win < Row * Col - EASY) {
            		printf("请输入坐标:");
            		scanf("%d %d", &x, &y);
            		if (x >= 1 && x <= row && y >= 1 && y <= col) {
            			if (mine[x][y] == '1') {
            				printf("炸死了\n");
            				DisplayBoard(mine, Row, Col);
            				break;
            			}
            			else//统计周围有几个地雷
            			{
            				int sum = GetMineCount(mine, x, y);
            				show[x][y] = sum + '0';//1+'0'='1'
            				DisplayBoard(show, Row, Col);
            				win++;
            			}
            		}
            		else {
            			printf("坐标错误重新输入");
            		}
            	}
            	if (win == Row * Col - EASY) {
            		printf("恭喜你排雷成功");
            		DisplayBoard(mine, Row, Col);
            	}
            }

                    game.h

            #pragma once
            #include#include#include#define Row 9
            #define Col 9
            #define Rows Row+2
            #define Cols Col+2
            #define EASY 10
            void InitBoard(char board[Rows][Cols], int rows, int cols, char set);//初始化棋盘
            void DisplayBoard(char board[Rows][Cols], int row, int col);//打印棋盘
            void SetMine(char board[Rows][Cols], int row, int col);//布置地雷
            void FindMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col);//找地雷