用10*10的矩形布雷
为了方便边缘雷的排查,定义12*12的数组,但显示10*10
mine.h
#define _CRT_SECURE_NO_WARNINGS
#ifndef _MINE_H_
#define _MINE_H_
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <time.h>
#include<stdlib.h>
#pragma warning(disable:4996)
#define ROW 12
#define COL 12
#define MINES 20 //雷的数量
char show_board[ROW][COL];//展示数组
char mine_board[ROW][COL];//布雷数组
void Menu();//菜单
void Game();//游戏函数
void SetMine(char mine_board[][COL], int row, int col);//布雷
void PlayGame(char show_board[][COL], char mine_board[][COL], int row, int col);//
int GetMineNum(char mine_board[][COL], int i, int j);//获得周围雷的数量
void ShowBoard(char show_board[][COL], int row, int col);//显示函数
void open_mine(char mine_board[][COL], char show_board[][COL], int x, int y);//展开周围空白
void safe_mine();//防止第一次被炸
#endif
mine.c
#include "mine.h"
void Menu()
{
printf("###########################################\n");
printf("## 1. Play 2. Exit ##\n");
printf("###########################################\n");
printf("Please Select:> ");
}
static int GetIndex(int start, int end) //[1, 10]
{
return rand() % (end - start + 1) + start;
}
//随机数布雷
void SetMine(char mine_board[][COL], int row, int col)
{
srand((unsigned long)time(NULL));
int mine_num = MINES;
while (mine_num){
int i_index = GetIndex(1, col - 2);
int j_index = GetIndex(1, col - 2);
if (mine_board[i_index][j_index] == '0'){
mine_board[i_index][j_index] = '1';
mine_num--;
}
}
}
//对应数组坐标周围雷数计算
int GetMineNum(char mine_board[][COL], int i, int j)
{
//'0 ' + '1'+'1'+'0'...+'0'
return mine_board[i - 1][j - 1] + mine_board[i - 1][j] + \
mine_board[i - 1][j + 1] + mine_board[i][j - 1] + \
mine_board[i][j + 1] + mine_board[i + 1][j - 1] + \
mine_board[i + 1][j] + mine_board[i + 1][j + 1] - 8 * '0'; //字符转化为数字
}
//显示
void ShowBoard(char show_board[][COL], int row, int col)
{
int i = 1;
int j = 1;
printf(" ");
for (; i <= col - 2; i++){
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row - 2; i++){
printf("%2d ", i);
for (j = 1; j <= col - 2; j++){
printf(" %c ", show_board[i][j]);
}
printf("\n");
}
}
void PlayGame(char show_board[][COL], char mine_board[][COL], int row, int col)
{
int i = 0;
int j = 0;
int total = (ROW - 2)*(COL - 2);
while (1){
ShowBoard(show_board, row, col);
printf("Please Enter Pos<x, y>: ");
scanf("%d%d", &i, &j);
if (i >= 1 && i <= row - 2 && j >= 1 && j <= col - 2){
if (mine_board[i][j] == '0'){
int num = GetMineNum(mine_board, i, j);
show_board[i][j] = num + '0';
open_mine(mine_board,show_board, i, j);
total--;
}
else{
ShowBoard(mine_board, row, col);
printf("Game Over! You Lose :(!\n");
break;
}
}
else{
printf("Enter Error, Try Again!\n");
continue;
}
if (total == MINES){
printf("You Win:)\n");
break;
}
}
}
void Game()
{
char show_board[ROW][COL];
char mine_board[ROW][COL];
memset(show_board, '*', sizeof(show_board));
memset(mine_board, '0', sizeof(mine_board));
SetMine(mine_board, ROW, COL);
safe_mine(show_board, mine_board,ROW, COL);
PlayGame(show_board, mine_board, ROW, COL);
}
//避免第一次炸死
void safe_mine(char show_board[][COL], char mine_board[][COL],int row,int col)
{
int x = 0;
int y = 0;
char ch = 0;
int count = 0;
int ret = 1;
ShowBoard(mine_board, row, col);//显示布雷,方便调试
while (1)
{
printf("\n");
ShowBoard(show_board, row, col);
printf("输入坐标扫雷\n");
scanf("%d%d", &x, &y);//只能输入1到10,输入错误重新输入
if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10))//判断输入坐标是否有误
{
if (mine_board[x][y] == '0')
{
char ch = GetMineNum(mine_board, x, y);
show_board[x][y] = ch + '0';//数字对应的ASCII值和数字字符对应的ASCII值相差48,即'0'的ASCII值
open_mine(mine_board, show_board, x, y);
break;
}
else //第一次踩到雷后补救
{
mine_board[x][y] = '0';
char ch = GetMineNum(mine_board, x, y);
show_board[x][y] = ch + '0';//数字对应的ASCII值和数字字符对应的ASCII值相差48,即'0'的ASCII值
open_mine(mine_board, show_board, x, y);
while (ret)//在其余有空的地方设置一个雷
{
int a = rand() % 10 + 1;//产生1到10的随机数,在数组下标为1到10的范围内布雷
int b = rand() % 10 + 1;//产生1到10的随机数,在数组下标为1到10的范围内布雷
if (mine_board[a][b] == '0')//找不是雷的地方布雷
{
mine_board[a][b] = '1';
ret--;
}
}break;
}
}
else//坐标错误
{
printf("输入错误重新输入\n");
break;
}
}
}
//坐标周围展开函数
void open_mine(char mine_board[][COL], char show_board[][COL], int x, int y)
{
if (GetMineNum(mine_board,x,y)==0)
{
show_board[x][y] = ' ';
if ((x - 1) > 0 && (y - 1) > 0 && (show_board[x - 1][y - 1] == '*'))
open_mine(mine_board, show_board, x - 1, y - 1);
if ((x - 1) > 0 && (y) > 0 && (show_board[x - 1][y] == '*'))
open_mine(mine_board, show_board, x - 1, y);
if ((x - 1) > 0 && (y + 1) > 0 && (show_board[x - 1][y + 1] == '*'))
open_mine(mine_board, show_board, x - 1, y + 1);
if ((x) > 0 && (y - 1) > 0 && (show_board[x][y - 1] == '*'))
open_mine(mine_board, show_board, x, y - 1);
if ((x) > 0 && (y + 1) > 0 && (show_board[x][y + 1] == '*'))
open_mine(mine_board, show_board, x, y + 1);
if ((x + 1) > 0 && (y - 1) > 0 && (show_board[x + 1][y - 1] == '*'))
open_mine(mine_board, show_board, x + 1, y - 1);
if ((x + 1) > 0 && (y) > 0 && (show_board[x + 1][y] == '*'))
open_mine(mine_board, show_board, x + 1, y);
if ((x + 1) > 0 && (y + 1) > 0 && (show_board[x + 1][y + 1] == '*'))
open_mine(mine_board, show_board, x + 1, y + 1);
}
else
show_board[x][y] = GetMineNum(mine_board, x, y) + '0';
}
main.c
#include "mine.h"
int main()
{
int select = 0;
int quit = 0;
while (!quit){
Menu();
scanf("%d", &select);
switch (select){
case 1:
Game();
break;
case 2:
printf("I Am Quit!\n");
quit = 1;
break;
default:
printf("Select Error! Try Again!\n");
break;
}
}
return 0;
}
调试:
显示布雷情况
输入坐标,展开空白区域
若第一次就踩雷
能够实现避免第一次不被炸死