在前面讲到了如何实现扫雷游戏
💡 扫雷游戏初版
今天来讲讲如何实现它的拓展,全部的代码放在文章的最后处
一.拓展的功能如下:
• 选择游戏难度
◦ 简单 9*9 棋盘,10个雷
◦ 中等 16*16棋盘,40个雷
◦ 困难 30*16棋盘,99个雷
• 展开周围的一片
• 标记雷
1.选择游戏难度
由于我们之前首先定义了棋盘的row col的大小,导致最多只能玩一种难度,这里我们稍微改动一下 ,给game函数传入参数,使得可以选择三种难度
2. 展开周围的一片
在之前的程序里 排查雷时,若是雷则被炸死,游戏结束; 若输入的坐标不是雷且周围没有雷,我们把它赋值为 0 ,若不是雷但周围有雷,赋值为它周围雷的个数。
现在我们需要展开周围的一片,如果不是雷则赋值为空格,来实现展开的效果
代码如下:
void Open(char mine[MAXSIZE][MAXSIZE], char show[MAXSIZE][MAXSIZE], int x, int y) {
int count = Get(mine, x, y);
if (count != 0) { //周围有雷
show[x][y] = '0' + count;
}
else if (show[x][y] != ' ') { //周围无雷 且 还没被展开
show[x][y] = ' ';
int i, j; //判断周围的坐标的周围有没有雷,直到有雷为止
for (i = x - 1; i <= x + 1; i++) {
for (j = y - 1; j <= y + 1; j++) {
Open(mine,show, i, j);
}
}
}
else { return ; }
}
3. 标记雷
在成功排查雷之后加一个标记雷的函数,标记地雷为 ? ,这样更方便我们进行后续的排雷。
代码如下:
void Sign(char show[MAXSIZE][MAXSIZE]) {
int i,x,y;
do{
printf("是否标记地雷?\n > 1开始标记 0退出标记\n");
scanf("%d", &i);
switch (i) {
case 0:
printf("您已退出标记\n");
break;
case 1:
printf("标记雷的坐标:");
scanf("%d %d", &x, &y);
if (show[x][y] == '*') {
show[x][y] ='?';
}
else printf("该坐标已被排查!请重新选择标记的位置\n");
break;
default:
printf("该指令无效,请重新下指令:\n");
}
}while(i);
}
二.源代码如下
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//#define ROW 9
//#define COL 9
//#define ROWS ROW+2
//#define COLS COL+2
//#define E 10
#define MAXSIZE 50
void Initboard(char a[MAXSIZE][MAXSIZE], int rows, int cols, char set);
void Displayboard(char a[MAXSIZE][MAXSIZE], int row, int col);
void Layoutboard(char a[MAXSIZE][MAXSIZE], int row, int col,int E);
void Find(char a[MAXSIZE][MAXSIZE], char b[MAXSIZE][MAXSIZE], int row, int col,int E);
void Open(char mine[MAXSIZE][MAXSIZE], char show[MAXSIZE][MAXSIZE], int , int y);
int Get(char show[MAXSIZE][MAXSIZE], int rows, int cols);
void Sign(char show[MAXSIZE][MAXSIZE]);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996)
#include"game.h"
void Initboard(char a[MAXSIZE][MAXSIZE], int rows, int cols, char set) {
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
a[i][j] = set;
}
}
}
void Displayboard(char a[MAXSIZE][MAXSIZE], int row, int col) {
int i, j,i1=0,i2=0,i3=0;
printf("__________________________________________\n");
printf(" ");
for (i = 0; i <= col; i++) {
if (i>29) {
printf("%d ", i3++);
}else if(i>19&&i<=29) printf("%d ", i2++);
else if(i>9&&i<=19) printf("%d ", i1++);
else printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++) {
printf("%-2d ", i);
for (j = 1; j <= col; j++) {
printf("%c ", a[i][j]);
}
printf("\n");
}
printf("__________________________________________\n");
}
void Layoutboard(char a[MAXSIZE][MAXSIZE], int row, int col,int E) {
int x, y;
int e = E;
while (e) {
x = rand() % row + 1;
y = rand() % col + 1;
if (a[x][y] != '1') {
a[x][y] = '1';
e--;
}
}
}
int Get(char mine[MAXSIZE][MAXSIZE], int x, int y) {
return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x - 1][y + 1] +
mine[x + 1][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] +
mine[x][y - 1] + +mine[x][y + 1] - 8 * '0');
}
void Find(char mine[MAXSIZE][MAXSIZE], char show[MAXSIZE][MAXSIZE], int row, int col,int E) {
int win = 0;
int x, y;
while (win < row * col - E) {
printf("请输入一个坐标:\n");
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;
}
if (mine[x][y] == '0') {
if ((show[x][y] >= '0' && show[x][y] <= '9') || show[x][y] == ' ') {
printf("不好意思,该坐标已经排查过,请重新输入:\n");
}
//如果不是雷,展开一片(用mine数组)
else {
printf("恭喜你,该坐标不是雷\n");
/*int count = get(mine, x, y);
show[x][y] = count + '0';*/
Open(mine, show, x, y);
Displayboard(show,row,col);
win++;
Sign(show);
}
}
}
else {
printf("输入错误,请重新输入:\n");
}
}
if (win == row * col - E) {
printf("恭喜你,排雷成功!!!\n");
Displayboard(mine,row,col);
}
}
void Open(char mine[MAXSIZE][MAXSIZE], char show[MAXSIZE][MAXSIZE], int x, int y) {
int count = Get(mine, x, y);
if (count != 0) { //周围有雷
show[x][y] = '0' + count;
}
else if (show[x][y] != ' ') { //周围无雷 且 还没被展开
show[x][y] = ' ';
int i, j; //判断周围的坐标的周围有没有雷,直到有雷为止
for (i = x - 1; i <= x + 1; i++) {
for (j = y - 1; j <= y + 1; j++) {
Open(mine,show, i, j);
}
}
}
else { return; }
}
void Sign(char show[MAXSIZE][MAXSIZE]) {
int i,x,y;
do{
printf("是否标记地雷?\n > 1开始标记 0退出标记\n");
scanf("%d", &i);
switch (i) {
case 0:
printf("您已退出标记\n");
break;
case 1:
printf("标记雷的坐标:");
scanf("%d %d", &x, &y);
if (show[x][y] == '*') {
show[x][y] ='?';
}
else printf("该坐标已被排查!请重新选择标记的位置\n");
break;
default:
printf("该指令无效,请重新下指令:\n");
}
}while(i);
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996)
#include "game.h"
void menu() {
printf("******************************\n");
printf("********** 1.简单难度 ********\n");
printf("********** 2.中等难度 ********\n");
printf("********** 3.困难难度 ********\n");
printf("********** 0.结束游戏 ********\n");
printf("******************************\n");
}
void game(int ROWS,int COLS,int ROW,int COL,int E) {
char mine[MAXSIZE][MAXSIZE];
char show[MAXSIZE][MAXSIZE];
//1.先初始化
Initboard(mine, ROWS, COLS, '0');
Initboard(show, ROWS, COLS, '*');
//Displayboard(mine,ROW,COL);
Displayboard(show, ROW, COL);
//2.给数组mine放置雷
Layoutboard(mine, ROW, COL,E);
//Displayboard(mine, ROW, COL);
//3.找出雷
Find(mine, show, ROW, COL,E);
}
int main() {
srand((unsigned int)time(NULL));
int n = 0;
do {
menu();
printf("请选择:<");
scanf("%d", &n);
switch (n) {
case 1:
game(11, 11, 9, 9, 10);
break;
case 2:
game(18, 18, 16, 16, 40);
break;
case 3:
game(18, 32, 16, 30, 99);
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (n);
}