这里写目录标题
初始化棋盘
这里的大体思路还是创建两个棋盘,一个它用来存放地雷判断条件,另一个用来看,假设要9×9的棋盘一定要创建11*11的,方便计数。
void initqipan(char a[ROW1S][COL1S], int row, int col, char set)
{/*这里的a数组是显示棋盘,并且未展开前,全部初始化为‘*’ */
for (int i = 1; i < row; i++)
{
for (int z = 1; z < col; z++)
{
a[i][z] = set;
}
}
}
显示棋盘
为了方便观看,加入了横标,竖标。
void show_board(char a[ROW1S][COL1S], int row, int col)
{
printf("----------扫雷---------\n");
for (int i = 0; i <= col; i++)
printf("%d ", i);
printf("\n");
for (int z = 1; z <= row; z++)
{
printf("%d ", z);
for (int i = 1; i <= col; i++)
printf("%c ", a[z][i]);
printf("\n");
}
printf("----------扫雷---------\n");
}
放置地雷
void set_mine(char mine[ROW1S][COL1S], int row, int col)
{/*我这里lei就是放置的地雷总数*/
int count = lei;
for (int i = 0; i < ROW1S; i++)
{
for (int z = 0; z < COL1S; z++)
{/*没有地雷就是表示为0*/
mine[i][z] = '0';
}
}
while(count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{/*1就是表示此处有地雷*/
mine[x][y] = '1';
count--;
}
}
}
记录周围地雷数目
int jishu(char mine[ROW1S][COL1S], int x, int y)
{/*访问周边8个格子,统计一共的地雷数量*/
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 openboard(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int x, int y)
{/*此处用的递归,访问8个格子,看看是否都无地雷,若是,展开*/
if (jishu(mine, x, y) == 0)
{
a[x][y] = ' ';
if (x > 0 && x <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x][y - 1] == '*')
openboard(mine, a, x, y - 1);
if (x - 1 > 0 && x - 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x - 1][y - 1] == '*')
openboard(mine, a, x - 1, y - 1);
if (x + 1 > 0 && x + 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x + 1][y - 1] == '*')
openboard(mine, a, x + 1, y - 1);
if (x > 0 && x <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x][y + 1] == '*')
openboard(mine, a, x, y + 1);
if (x + 1 > 0 && x + 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x + 1][y + 1] == '*')
openboard(mine, a, x, y - 1);
if (x + 1 > 0 && x + 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
openboard(mine, a, x + 1, y);
if (x - 1 > 0 && x - 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
openboard(mine, a, x + 1, y);
if (x - 1 > 0 && x - 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x - 1][y + 1] == '*')
openboard(mine, a, x - 1, y + 1);
}
else/*结束条件*/
a[x][y] = jishu(mine, x, y) + '0';
}
判断条件
int wins(char a[ROW1S][COL1S])
{
int count = 0;
for (int i = 1; i <= ROW1; i++)
{
for (int z = 1; z <= COL1; z++)
{/*看看棋盘中还有多少个‘*’ */
if (a[i][z] == '*')
count++;
}
}
return count;
}
void is_win(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int row, int col)
{
int x, y,win=wins(a);
while (win > lei) {
printf("请输入坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col&&a[x][y]=='*')
{
if (mine[x][y] == '1') {
system("cls");
show_board(mine,row,col);
printf("你被炸死了\n");
break;
}
else
{
openboard(mine, a, x, y);
system("cls");
show_board(a, row, col);
}
}
else
printf("坐标非法,请重新输入\n");
}/*每次扫描过后,棋盘中的*号会变少,直到剩余的*号全是地雷*/
if (win == lei)
{
printf("你赢了\n");
system("cls");
show_board(mine, row, col);
}
}
格局构造
void game()
{
char a[ROW1S][COL1S] = { 0 };
char mine[ROW1S][COL1S] = { 0 };
/*初始化棋盘*/
initqipan(a, ROW1S, COL1S, '*');
initqipan(mine, ROW1S, COL1S, '0');
/*埋地雷*/
set_mine(mine, ROW1, COL1);
show_board(a, ROW1, COL1);
/*周边地雷计数*/
jishu(mine, ROW1, COL1);
/*输赢判断*/
is_win(mine, a, ROW1, COL1);
}
整体实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <Windows.h>
#include <time.h>
#define ROW1 9
#define COL1 9
#define ROW1S ROW1+2
#define COL1S COL1+2
#define lei 10
void meun()
{
printf("*****************\n");
printf("****1. 开始 ****\n");
printf("*****************\n");
printf("****0. 退出 ****\n");
printf("*****************\n");
}
void initqipan(char a[ROW1S][COL1S], int row, int col, char set)
{
for (int i = 1; i < row; i++)
{
for (int z = 1; z < col; z++)
{
a[i][z] = set;
}
}
}
void show_board(char a[ROW1S][COL1S], int row, int col)
{
printf("----------扫雷---------\n");
for (int i = 0; i <= col; i++)
printf("%d ", i);
printf("\n");
for (int z = 1; z <= row; z++)
{
printf("%d ", z);
for (int i = 1; i <= col; i++)
printf("%c ", a[z][i]);
printf("\n");
}
printf("----------扫雷---------\n");
}
void set_mine(char mine[ROW1S][COL1S], int row, int col)
{
int count = lei;
for (int i = 0; i < ROW1S; i++)
{
for (int z = 0; z < COL1S; z++)
{
mine[i][z] = '0';
}
}
while(count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
int jishu(char mine[ROW1S][COL1S], 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 openboard(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int x, int y)
{
if (jishu(mine, x, y) == 0)
{
a[x][y] = ' ';
if (x > 0 && x <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x][y - 1] == '*')
openboard(mine, a, x, y - 1);
if (x - 1 > 0 && x - 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x - 1][y - 1] == '*')
openboard(mine, a, x - 1, y - 1);
if (x + 1 > 0 && x + 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x + 1][y - 1] == '*')
openboard(mine, a, x + 1, y - 1);
if (x > 0 && x <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x][y + 1] == '*')
openboard(mine, a, x, y + 1);
if (x + 1 > 0 && x + 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x + 1][y + 1] == '*')
openboard(mine, a, x, y - 1);
if (x + 1 > 0 && x + 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
openboard(mine, a, x + 1, y);
if (x - 1 > 0 && x - 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
openboard(mine, a, x + 1, y);
if (x - 1 > 0 && x - 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x - 1][y + 1] == '*')
openboard(mine, a, x - 1, y + 1);
}
else
a[x][y] = jishu(mine, x, y) + '0';
}
int wins(char a[ROW1S][COL1S])
{
int count = 0;
for (int i = 1; i <= ROW1; i++)
{
for (int z = 1; z <= COL1; z++)
{
if (a[i][z] == '*')
count++;
}
}
return count;
}
void is_win(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int row, int col)
{
int x, y,win=wins(a);
while (win > lei) {
printf("请输入坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col&&a[x][y]=='*')
{
if (mine[x][y] == '1') {
system("cls");
show_board(mine,row,col);
printf("你被炸死了\n");
break;
}
else
{
openboard(mine, a, x, y);
system("cls");
show_board(a, row, col);
}
}
else
printf("坐标非法,请重新输入\n");
}
if (win == lei)
{
printf("你赢了\n");
system("cls");
show_board(mine, row, col);
}
}
void game()
{
char a[ROW1S][COL1S] = { 0 };
char mine[ROW1S][COL1S] = { 0 };
initqipan(a, ROW1S, COL1S, '*');
initqipan(mine, ROW1S, COL1S, '0');
set_mine(mine, ROW1, COL1);
show_board(a, ROW1, COL1);
jishu(mine, ROW1, COL1);
is_win(mine, a, ROW1, COL1);
jishu(mine, ROW1, COL1);
}
int main()
{
srand((unsigned int)time(NULL));
int input;
do
{
meun();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:printf("开始游戏\n"); game(); break;
case 0:printf("退出游戏\n"); break;
default:printf("请重新输入\n"); break;
}
} while (input);
}