C语言实现扫雷附完整代码

一、理清逻辑

我们先来看一下实现扫雷的基本逻辑

  • 1.打印游戏菜单
  • 2.创建并初始化二维数组
  • 3.布置雷
  • 4.进行排雷

二、创建文件

我创建了三个文件,分别为test.c、game.h和game.c

test.c文件用于实现进入游戏、退出游戏、判断输赢、打印菜单等逻辑

game.c用于编写游戏的主要实现方法

game.h存放头文件和函数的声明

三、具体步骤

1.打印菜单

void menu()

{

printf("**********************************\n");

printf("*********** 1.start **********\n");

printf("*********** 0. exit **********\n");

printf("**********************************\n");

}

void test()

{

int input = 0;

srand((unsigned int)time(NULL));

do

{

menu();

printf("请输入:>");

scanf("%d", &input);

switch (input)

{

case 1:

printf("游戏开始\n");

game();

break;

case 0:

printf("游戏结束\n");

break;

default :

printf("非法输入,请重新输入\n");

break;

}

} while (input);

}

2.创建二维数组

因为我们想实现一个9*9的扫雷,所以考虑到数组越界的问题,我们要创建一个11*11的二维数组,

需要同时去创建两个二维数组,mine数组用来查看雷的位置和show数组来展示排雷过程。

void game()

{

char mine[ROWS][COLS] = { 0 };

char show[ROWS][COLS] = { 0 };

}

3.初始化二维数组并打印棋盘

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9

#define COL 9

#define ROWS ROW+2

#define COLS COL+2

#define EASY_COUNT 10

//初始化二维数组

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

//打印棋盘

void DisplayBoard(char board[ROWS][COLS], int row, int col);

void game()

{

char mine[ROWS][COLS] = { 0 };

char show[ROWS][COLS] = { 0 };

//初始化二维数组

InitBoard(mine, ROWS, COLS, '0');

InitBoard(show, ROWS, COLS, '*');

//打印棋盘

DisplayBoard(mine, ROW, COL);

DisplayBoard(show, ROW, COL);

}

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;

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");

}

}

效果图

4.布置雷

//设置雷

void setMine(char mine[ROWS][COLS], int row, int col);

void setMine(char mine[ROWS][COLS], int row, int col)

{

int count = EASY_COUNT;

while (count)

{

int x = rand() % row + 1;

int y = rand() % col + 1;

if (mine[x][y] == '0')

{

mine[x][y] = '1';

count--;

}

}

}

效果图

5.排查雷(内含判断胜负)

玩家输入坐标,若该位置踩到雷游戏结束,若未踩到雷,显示周边雷的个数。

若除雷位置外的格子全部踩满,则游戏胜利。

int get_mine_count(char mine[ROWS][COLS],int x,int y)

{

return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +

mine[x][y - 1] + mine[x][y + 1] +

mine[x - 1][y - 1] + mine[x - 1][y] + 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_COUNT)

{

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 n = get_mine_count(mine, x, y);

show[x][y] = n + '0';

DisplayBoard(show, ROW, COL);

win++;

}

}

else

{

printf("输入坐标非法请重新输入:>");

}

if (win == row * col - EASY_COUNT)

{

printf("恭喜你,排雷成功!\n");

DisplayBoard(mine, ROW, COL);

}

}

}

四、完整代码

game.h

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9

#define COL 9

#define ROWS ROW+2

#define COLS COL+2

#define EASY_COUNT 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 mine[ROWS][COLS], int row, int col);

//排查雷

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void game()

{

char mine[ROWS][COLS] = { 0 };

char show[ROWS][COLS] = { 0 };

//初始化二维数组

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

}

void menu()

{

printf("**********************************\n");

printf("*********** 1.start **********\n");

printf("*********** 0. exit **********\n");

printf("**********************************\n");

}

void test()

{

int input = 0;

srand((unsigned int)time(NULL));

do

{

menu();

printf("请输入:>");

scanf("%d", &input);

switch (input)

{

case 1:

printf("游戏开始\n");

game();

break;

case 0:

printf("游戏结束\n");

break;

default :

printf("非法输入,请重新输入\n");

break;

}

} while (input);

}

int main()

{

test();

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;

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");

}

}

void setMine(char mine[ROWS][COLS], int row, int col)

{

int count = EASY_COUNT;

while (count)

{

int x = rand() % row + 1;

int y = rand() % col + 1;

if (mine[x][y] == '0')

{

mine[x][y] = '1';

count--;

}

}

}

int get_mine_count(char mine[ROWS][COLS],int x,int y)

{

return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +

mine[x][y - 1] + mine[x][y + 1] +

mine[x - 1][y - 1] + mine[x - 1][y] + 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_COUNT)

{

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 n = get_mine_count(mine, x, y);

show[x][y] = n + '0';

DisplayBoard(show, ROW, COL);

win++;

}

}

else

{

printf("输入坐标非法请重新输入:>");

}

if (win == row * col - EASY_COUNT)

{

printf("恭喜你,排雷成功!\n");

DisplayBoard(mine, ROW, COL);

}

}

}

五、待改进

在判断周围有没有雷的时候,show中可以显示周围雷的个数,但是上面写法中只能一个一个位置进行判断,若周围位置都为0一个个去排查未免浪费时间。

我们可以通过一个方法去快速排查,先判断该坐标有无雷,没有就先将该坐标置为空格,然后按照相同的方法扫描它周围的情况。

//递归排雷

void count(char Show[ROWS][COLS], char Mine[ROWS][COLS], int x, int y)

{

int i = 0;

int j = 0;

if (get_mine_count(Mine, x, y) == 0)

{

Show[x][y] = ' ';

for (i = x - 1; i <= x + 1; i++)

{

for (j = y - 1; j <= y + 1; j++)

{

if (i > 0 && i <= ROW && j > 0 && j <= COL && Mine[i][j] != '1' && Show[i][j] == '*')

{

count(Show, Mine, i, j);

}

}

}

}

else

Show[x][y] = '0' + get_mine_count(Mine, x, y);

}

到此这篇关于C语言实现扫雷的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

以上是 C语言实现扫雷附完整代码 的全部内容, 来源链接: utcz.com/p/247778.html

回到顶部