经过几天的努力,完成如下的c语言扫雷
主要思想是构建两个二维数组,但是构建出来的二维数组要比打印出来的大一圈,因为这样才会在后续统计雷数的时候更加方便。
然后两个二维数组,其中一个二维数组是我用来布置雷的,而另一个是展示给玩家看的。
在我的棋盘布置雷之后,让玩家在他的雷盘进行选择。
- 如果选择的坐标在我的棋盘是雷,则炸。
- 如果不是雷,则统计周围的雷数
1.统计周围雷数,如果周围一颗雷都没有,则展开继续统计。
2.如果周围有雷,则显示周围的雷数。
3.玩家进行一步一步的扫雷过程中,如果遇到雷,那边炸掉,重新游戏
如果没遇到雷,最后统计玩家没掀开的格子数量,如果数量是等于雷的数量,那游戏玩家获胜。
以上就是大体 的思路,下面是代码展示:
头文件game.h
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 9
#define COL 9
#define ROWS ROW +2
#define COLS COL +2
#define MINE 9
void InitBoard(char board[ROWS][COLS], int row, int col, char set);
void Display(char board[ROWS][COLS], int row, int col);
void PutMine(char board[ROWS][COLS], int row, int col);
void Saolei(char MineBoard[ROWS][COLS], int ShowBoard[ROWS][COLS], int rol, int col);
int NearMine(char mine[COLS][ROWS], int x, int y);
void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int CountBlank(char show[ROWS][COLS], int row, int col);
初始化
void InitBoard(char MineBoard[ROWS][COLS], int row, int col, char set)//初始化棋盘
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
MineBoard[i][j] = set;
}
}
}
打印棋盘
void Display(char board[ROWS][COLS], int row, int col)//打印棋盘
{
{
int i = 0;
int j = 0;
printf(" ");
for (j = 0; j < col ; j++)//列序号
{
printf("%d ",j+1);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d", i);//行序号
printf(" ");
for (j = 1; j <= col; j++)
{
printf(" %c ", board[i][j]);
if (j <= col - 1)
{
printf("|");
}
}
printf("\n");
printf(" ");
for (j = 1; j <= col; j++)
{
if (i <= row - 1)
{
printf("---");
if (j <= col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
}
放随机雷
void PutMine(char board[ROWS][COLS], int row, int col)//布置雷
{
int x = 0;
int y = 0;
int count = MINE;
while (count)
{
x = rand() % MINE + 1;
y = rand() % MINE + 1;
if (x>0 && x <= row && y>0 && y <= col && board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
统计周围雷个数
int NearMine(char mine[COLS][ROWS], 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 NoMine(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y)
{
int ret = NearMine(mine, x, y);
if (ret == 0)
{
show[x][y] = ' ';
if ((x - 1)>0 && (y - 1)>0 && (show[x - 1][y - 1] == '*'))
NoMine(mine, show, x - 1, y - 1);
if ((x - 1)>0 && (y)>0 && (show[x - 1][y] == '*'))
NoMine(mine, show, x - 1, y);
if ((x - 1)>0 && (y + 1)>0 && (show[x - 1][y + 1] == '*'))
NoMine(mine, show, x - 1, y + 1);
if ((x)>0 && (y - 1)>0 && (show[x][y - 1] == '*'))
NoMine(mine, show, x, y - 1);
if ((x)>0 && (y + 1)>0 && (show[x][y + 1] == '*'))
NoMine(mine, show, x, y + 1);
if ((x + 1)>0 && (y - 1)>0 && (show[x + 1][y - 1] == '*'))
NoMine(mine, show, x + 1, y - 1);
if ((x + 1)>0 && (y)>0 && (show[x + 1][y] == '*'))
NoMine(mine, show, x + 1, y);
if ((x + 1)>0 && (y + 1)>0 && (show[x + 1][y + 1] == '*'))
NoMine(mine, show, x - 1, y - 1);
}
else
{
show[x][y] = ret + '0';
}
}
统计玩家没掀开的格子个数
int CountBlank(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
count++;
}
}
return count;
}
玩家扫雷
void Saolei(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col)
{
int x = 0;
int y = 0;
int flag = 1;
int ret = 0;
do
{
printf("请输入扫雷坐标:>");
scanf("%d%d", &x, &y);
{
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '0' && show[x][y] == '*')
{
NoMine(mine, show, x, y);
/*Display(mine, ROW, COL);*/
Display(show, ROW, COL);
ret = CountBlank(show, ROW, COL);
if (ret == MINE)
{
printf("你赢了\n");
break;
}
}
if (mine[x][y] == '1' && show[x][y] == '*')
{
show[x][y] = 'S';
Display(show, ROW, COL);
printf("你被炸死了,雷图如下\n");
Display(mine, ROW, COL);
flag = 0;
}
}
else
{
printf("坐标非法请重新输入\n");
}
}
} while (flag);
}
改装升级:第一次碰雷不炸开:设置count,每次输入坐标count便加1,在count=1时碰雷游戏继续,代码如下
void Saolei(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col)
{
int x = 0;
int y = 0;
int flag = 1;
int ret = 0;
int count = 0;
do
{
printf("请输入扫雷坐标:>");
scanf("%d%d", &x, &y);
count++;
{
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '0' && show[x][y] == '*')
{
NoMine(mine, show, x, y);
/*Display(mine, ROW, COL);*/
Display(show, ROW, COL);
ret = CountBlank(show, ROW, COL);
if (ret == MINE)
{
printf("你赢了\n");
break;
}
}
if (mine[x][y] == '1' && show[x][y] == '*'&& count == 1)
{
printf("你碰到雷了,第一次下子不被炸死\n");
}
if (mine[x][y] == '1' && show[x][y] == '*'&& count != 1)
{
show[x][y] = 'S';
Display(show, ROW, COL);
printf("你被炸死了,雷图如下\n");
Display(mine, ROW, COL);
flag = 0;
}
}
else
{
printf("坐标非法请重新输入\n");
}
}
} while (flag);
}
主函数text.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 MineBoard[ROWS][COLS] = { 0 };
char ShowBoard[ROWS][COLS] = { 0 };
InitBoard(MineBoard, ROWS,COLS, '0');
PutMine(MineBoard, ROW, COL);
Display(MineBoard, ROW, COL);
InitBoard(ShowBoard, ROWS, COLS, '*');
Display(ShowBoard, ROW,COL);
Saolei(MineBoard, ShowBoard, 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;
}
实现图片