头文件:
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
//9X9用户接受信息排雷盘
#define ROW 9
#define COL 9
//9X9实际排雷盘
#define ROWS (ROW + 2)
#define COLS (COL + 2)
//12X12用户接受信息排雷盘
#define ROWT 12
#define COLT 12
//9X9实际排雷盘
#define ROWTS (ROWT + 2)
#define COLTS (COLT + 2)
//难度——雷数
#define EASY 12
#define MID 32
#define DIF 56
#define EASYP (EASY+18)
#define MIDP (MID + 18)
#define DIFP (DIF + 24)
//游戏菜单
void menu(void);
//游戏内核
int game(int * input);
//排雷盘选择
int relectPan(void);
//实际雷盘数组内容初始化
void InitMineOrShow(char ms[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisPlayPan(char ms[ROW][COL], int rows, int cols, int mine_count);
//设置雷数
int SetMine(char mine[ROW][COL], int rows, int cols,int kan);
//输入坐标,并判断坐标是否正确
int PanDuanXY(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols);
//排查雷
int FineMine(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols, int x, int y);
//坐标扩散——无雷情况
void SpreadXY(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols, int x, int y);
//排查零雷过程
int minesuceed(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols, int x, int y);
//检查是否排查完
int AllFind(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols);
//踩雷——清雷盘
void clearboard(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols);
//排雷排完——清雷盘
void clearboardplus(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols);
//标记
int biao(char sh[ROW][COL], int rows, int cols);
游戏内核源代码:
#include "game.h"
//游戏菜单
void menu(void)
{
printf(" ————————扫雷游戏————————\n");
printf("\n");
printf(" 1.play \n");
printf("\n");
printf(" 0.exit \n");
printf("\n");
printf(" ————————扫雷游戏————————\n");
printf("\n");
}
//游戏内核
int game(int* input)
{
//排雷盘模式选择
int relect = relectPan();
system("cls");//清屏
if (9 == relect)
{
//创建实际棋盘
char mine[ROWS][COLS] = { 0 };
//创建用户接受信息棋盘
char show[ROWS][COLS] = { 0 };
//初始化数组的内容为指定的内容
//mine 数组在没有布置雷的时候,都是'0'
InitMineOrShow(mine, ROWS, COLS, '0');
//show 数组在没有排查雷的时候,都是'*'
InitMineOrShow(show, ROWS, COLS, '?');
//埋雷
int mine_count = SetMine(mine, ROW, COL, relect);
system("cls");
DisPlayPan(mine, ROW, COL, mine_count);
//打印用户接收信息棋盘
DisPlayPan(show, ROW, COL, mine_count);
while (1)
{
int pailei = -4;
int dian = -1;
while (1)
{
printf("选择标记还是排雷,又或者是中途退出游戏(1,2,0):>");
scanf("%d", &dian);
while (getchar() != '\n');
if (dian == 1)
{
int is_biao = biao(show, ROW, COL);
if (0 == is_biao)
{
printf("游戏中途退出成功!\n");
return 0;
}
break;
}
else if (dian == 2)
{
//排查雷
pailei = PanDuanXY(mine, show, ROW, COL);
break;
}
dian = -1;
printf("输入错误,请重新输入!\n");
}
//中途退出游戏
if (pailei == -10 || dian == 0)
{
printf("退出游戏成功!\n");
*input = 0;//退出游戏
return 0;
}
//system("cls");
DisPlayPan(show, ROW, COL, mine_count);
if (pailei == -3)
{
printf("踩雷——失败!\n");
return;
}
//检查排雷
int t = AllFind(mine, show, ROW, COL);
if (t == 1)
{
clearboardplus(mine, show, ROW, COL);
system("cls");
DisPlayPan(show, ROW, COL, mine_count);
printf("你已经排雷完毕,游戏结束!\n");
return;
}
}
}
if (12 == relect)
{
//创建实际棋盘
char mine[ROWTS][COLTS] = { 0 };
//创建用户接受信息棋盘
char show[ROWTS][COLTS] = { 0 };
//初始化数组的内容为指定的内容
//mine数字在没有布置雷的时候,都是'0'
InitMineOrShow(mine, ROWTS, COLTS, '0');
//show 数组在没有排查雷的时候,都是'*'
InitMineOrShow(show, ROWTS, COLTS, '?');
//埋雷
int mine_count = SetMine(mine, ROWT, COLT, relect);
//DisPlayPan(mine, ROWT, COLT,mine_count);
//打印用户接收信息棋盘
DisPlayPan(show, ROWT, COLT, mine_count);
while (1)
{
int pailei = -4;
int dian = -1;
while (1)
{
printf("选择标记还是排雷,又或者是退出游戏(1,2,0):>");
scanf("%d", &dian);
while (getchar() != '\n');
if (dian == 1)
{
int is_biao = biao(show, ROWT, COLT);
if (0 == is_biao)
{
printf("游戏中途退出成功!\n");
return 0;
}
break;
}
else if (dian == 2)
{
//排查雷
pailei = PanDuanXY(mine, show, ROWT, COLT);
break;
}
dian = -1;
printf("输入错误,请重新输入!\n");
}
//中途退出游戏
if (pailei == -10 || dian == 0)
{
printf("退出游戏成功!\n");
*input = 0;//退出游戏
return 0;
}
system("cls");
DisPlayPan(show, ROWT, COLT, mine_count);
if (pailei == -3)
{
printf("踩雷——失败!\n");
return;
}
//检查排雷
int t = AllFind(mine, show, ROWT, COLT);
if (t == 1)
{
clearboardplus(mine, show, ROWT, COLT);
system("cls");
DisPlayPan(show, ROWT, COLT, mine_count);
printf("你已经排雷完毕,游戏结束!\n");
return;
}
}
}
}
//排雷盘选择
int relectPan(void)
{
int relect = -1;
while (1)
{
char inputmode[7] = { 0 };
printf("请选择棋盘大小——(9x9、12x12):>");
scanf("%s", inputmode);
if (0 == strcmp(inputmode, "9x9"))
{
relect = 9;
break;
}
if (0 == strcmp(inputmode, "12x12"))
{
relect = 12;
break;
}
printf("选择错误,请重新输入!\n");
}
return relect;
}
//实际雷盘或者用户接收信息雷盘数组内容初始化
void InitMineOrShow(char ms[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; ++i)
{
int j = 0;
for (j = 0; j < cols; ++j)
{
ms[i][j] = set;
}
}
}
//打印用户接收信息棋盘
void DisPlayPan(char ms[ROW][COL], int rows, int cols, int mt)
{
int i = 0;
printf("——————————————扫雷游戏———————————————\n");
if (cols == 9)
for (i = 1; i <= cols; ++i)
{
if (i != rows)
printf(" %d ", i);
else
printf(" %d \n", i);
}
if (cols == 12)
for (i = 1; i <= cols; ++i)
{
if (i != cols && i != cols - 1 && i != cols - 2)
printf(" %d ", i);
else if (i == cols - 1 || i == cols - 2)
printf(" %d ", i);
else
printf(" %d \n", i);
}
for (i = 1; i <= cols; ++i)
{
if (i != cols)
printf(" ___");
else
printf(" ___ \n");
}
for (i = 1; i <= rows; ++i)
{
int j = 0;
for (j = 1; j <= cols; ++j)
{
if (j != cols)
printf("| %c ", ms[i][j]);
else
printf("| %c | %d\n", ms[i][j], i);
}
for (j = 1; j <= cols; ++j)
{
if (j != cols)
printf("|___");
else
printf("|___|\n");
}
}
printf("\n");
printf("地雷数:%d", mt);
printf("\n");
; printf("——————————————扫雷游戏———————————————\n");
}
//设置雷数
int SetMine(char ms[ROW][COL], int rows, int cols, int kan)
{
if (kan == ROW)
{
int rel = -1;
while (1)
{
char relectmodelei[7] = { 0 };
printf("选择难度mode(简单——easy、中等——mid、困难——dif):>");
scanf("%s", relectmodelei);
if (0 == strcmp(relectmodelei, "easy"))
{
rel = 1;
break;
}
if (0 == strcmp(relectmodelei, "mid"))
{
rel = 2;
break;
}
if (0 == strcmp(relectmodelei, "dif"))
{
rel = 3;
break;
}
printf("选择错误,请重新输入!\n");
}
//难度EASY
if (1 == rel)
{
int count = EASY;
while (count)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (ms[x][y] == '0')
{
ms[x][y] = '*';
count--;
}
}
return EASY;
}
//难度MID
if (2 == rel)
{
int count = MID;
while (count)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (ms[x][y] == '0')
{
ms[x][y] = '*';
count--;
}
}
return MID;
}
//难度DIF
if (3 == rel)
{
int count = DIF;
while (count)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (ms[x][y] == '0')
{
ms[x][y] = '*';
count--;
}
}
return DIF;
}
}
else if (kan == ROWT)
{
int rel = -1;
while (1)
{
char relectmodelei[7] = { 0 };
printf("选择难度mode(简单——easy、中等——mid、困难——dif):>");
scanf("%s", relectmodelei);
if (0 == strcmp(relectmodelei, "easy"))
{
rel = 1;
break;
}
if (0 == strcmp(relectmodelei, "mid"))
{
rel = 2;
break;
}
if (0 == strcmp(relectmodelei, "dif"))
{
rel = 3;
break;
}
printf("选择错误,请重新输入!\n");
}
//难度EASY
if (1 == rel)
{
int count = EASYP;
while (count)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (ms[x][y] == '0')
{
ms[x][y] = '*';
count--;
}
}
return EASYP;
}
//难度MID
if (2 == rel)
{
int count = MIDP;
while (count)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (ms[x][y] == '0')
{
ms[x][y] = '*';
count--;
}
}
return MIDP;
}
//难度DIF
if (3 == rel)
{
int count = DIFP;
while (count)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (ms[x][y] == '0')
{
ms[x][y] = '*';
count--;
}
}
return DIFP;
}
}
}
//输入坐标,并判断坐标是否正确
int PanDuanXY(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols)
{
//输入坐标,并且判断坐标是否正确
int inputpai = 1;
int x = -2;
int y = -2;
while (1)
{
printf("请输入要排查的坐标(中途退出坐标为0 0):>");
scanf("%d%d", &x, &y);
while (getchar() != '\n');
if (x == 0 && y == 0)//中途退出设置
{
return -10;
}
if (x >= 1 && x <= rows && y >= 1 && y <= cols && sh[x][y] == '?')
{
inputpai = 0;
}
if (inputpai == 0)
{
break;
}
printf("坐标输入错误,请重新输入!\n");
x = -2;
y = -2;
}
return FineMine(mi, sh, rows, cols, x, y);
}
//排查雷,并且转换图案
int FineMine(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols, int x, int y)
{
//首先判断这个坐标是不是雷
if (mi[x][y] == '*')
{
sh[x][y] = mi[x][y];
//一旦踩雷就把所有的类都换上,其余部分为空格
clearboard(mi, sh, rows, cols);
return -3;
}
else if (mi[x][y] != '*')//不是雷的情况
{
int count = minesuceed(mi, sh, rows, cols, x, y);
if (0 == count && sh[x][y] != ' ' && sh[x][y] != 'X')
{
sh[x][y] = ' ';
SpreadXY(mi, sh, rows, cols, x, y);
}
else if (sh[x][y] != 'X' && 0 != count)
{
sh[x][y] = count + '0';
}
return -4;
}
}
//坐标扩散——无雷情况
void SpreadXY(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols, int x, int y)
{
int i = -1;
for (i = x - 1; i <= x + 1; ++i)
{
int j = -1;
for (j = y - 1; j <= y + 1; ++j)
{
if (((i != x) || (j != y)) && ((0 != i) || (0 != j)))
{
int count = -1;
count = minesuceed(mi, sh, rows, cols, i, j);
//找到x,y周围有一个无雷的坐标,先把它化为空格,然后在排查它
if (sh[i][j] != 'X' && 0 == count && sh[i][j] == '?' && sh[i][j] != ' ')
{
sh[i][j] = ' ';
//x,y坐标的周围有一个的坐标b,b坐标的周围没有雷,就递归SpreadXY函数
SpreadXY(mi, sh, rows, cols, i, j);
}
else if (sh[i][j] != 'X' && 0 != count && sh[i][j] == '?')//最后才把坐标位置转化为数字
{
sh[i][j] = count + '0';
}
}
}
}
return;
}
//排查零雷过程
int minesuceed(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols, int x, int y)
{
//不是雷之后,每查到一个雷就count++;
int count = 0;
int i = x - 1;
for (i = x - 1; i <= x + 1; ++i)
{
int j = y - 1;
for (j = y - 1; j <= y + 1; ++j)
{
if (i != x || j != y)
{
if (mi[i][j] == '*')
count++;
}
}
}
return count;
}
//检查是否排查完
int AllFind(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols)
{
/*//没有排完
int i = 0;
for (i = 1; i <= rows; ++i)
{
int j = 0;
for (j = 1; j <= cols; ++j)
{
if (sh[i][j] == '?'&& sh[i][j] != '*')
{
return (++zero_count);
}
}
}
*/
//排查完毕
int i = 0;
for (i = 1; i <= rows; ++i)
{
int j = 0;
for (j = 1; j <= cols; ++j)
{
if (mi[i][j] != '*' && sh[i][j] == '?')
{
return 0;
}
}
}
return 1;
}
//踩雷——清雷盘
void clearboard(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols)
{
int i = 1;
for (i = 1; i <= rows; ++i)
{
int j = 1;
for (j = 1; j <= cols; ++j)
{
if (mi[i][j] == '*')
sh[i][j] = mi[i][j];
if (sh[i][j] == '?')
sh[i][j] = ' ';
}
}
}
//排雷排完——清雷盘
void clearboardplus(char mi[ROW][COL], char sh[ROW][COL], int rows, int cols)
{
int i = 1;
for (i = 1; i <= rows; ++i)
{
int j = 1;
for (j = 1; j <= cols; ++j)
{
if (mi[i][j] == '*')
{
sh[i][j] = mi[i][j];
}
}
}
for (i = 1; i <= rows; ++i)
{
int j = 1;
for (j = 1; j <= cols; ++j)
{
if (mi[i][j] == '?')
{
sh[i][j] = ' ';
}
}
}
}
//标记
int biao(char sh[ROW][COL], int rows, int cols)
{
int x = -2;
int y = -2;
while (1)
{
x = -2;
y = -2;
printf("请你输入要标记或者取消标记的坐标,又或者退出游戏(0 0):>");
scanf("%d%d", &x, &y);
while (getchar() != '\n');
if (x >= 1 && x <= rows && y <= cols && y >= 1)
{
if (sh[x][y] == '?' || sh[x][y] == 'X')
break;
}
if (0 == x && 0 == y)
{
return 0;
}
printf("输入错误,请重新输入!\n");
}
if (sh[x][y] == '?')
{
sh[x][y] = 'X';
}
else if (sh[x][y] == 'X')
{
sh[x][y] = '?';
}
return 1;
}
游戏运行源代码文件:
#include "game.h"
/*
扫雷游戏(黑色控制台窗口)
*/
int main()
{
srand((unsigned int)time(NULL));//设置随机数的起始点
int input = 0;
do
{
menu();
printf("请选择(1,0):>");
scanf("%d", &input);
getchar();
switch (input)
{
case 1:
system("cls");
int input = game(&input);
if (0 == input)
{
return;
}
break;
case 0:
printf("退出游戏.\n");
break;
default:
printf("选择错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
(以上就是扫雷在黑白指令框的所有代码,无雷扩散是属于递归范畴)