之前写的扫雷,有一些标雷的小bug
//扫雷 40个雷 16*16棋盘
//不要尝试将不是雷的位置标雷
//除了标雷以外,不要尝试输入大于(16,16)或小于(0,0)的坐标
//如果输入坐标之后没反应,说明你踩到了雷,请继续输下一个坐标
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
int coordinate_x;//用户输入坐标
int coordinate_y;
int board_A[16][16]={0};//显示雷的位置
int board_B[16][16]={0};//显示所有雷数,88表示雷
int board_C[16][16]={0};//用99,77代表是否在用户界面显示某格
int board_D[16][16]={};//用户界面
int main()
{
//随机数种子
srand((int)time(NULL));//产生随机数的种子
//声明函数
void print_board_A(); //输出棋盘A
void print_board_B(); //输出棋盘B
void print_board_C(); //输出棋盘C
void print_board_D(); //输出棋盘D
void print_line(); //输出分割线
int rand_number(); //产生1~100的随机数
void mine_initialize(); //把40个0变成1
void calculate_A_to_B(); //计算棋盘B
void input_coordinate();//输入要点击的坐标
void spread_B_to_C(int coordinate_x,int coordinate_y); //点击后从B到C的展开
void spread_C_to_C();//点击后从C到C的展开
int unknown_num() ;//剩余雷的个数
//声明变量
int unknown=16*16;
//主体
rand_number();
mine_initialize();
print_board_D();
calculate_A_to_B();
print_board_A();
print_board_B();
for(;unknown=40;)
{
input_coordinate();
spread_B_to_C(coordinate_x,coordinate_y);
spread_C_to_C();
// print_board_C();
system("cls");
print_board_D();
unknown=unknown_num();
if(unknown==40)
{
printf("恭喜你,你赢了!");
break;
}
}
}
//函数
void print_board_A()//输出漂亮的棋盘A
{
int i,j;
void print_line();
printf(" 棋 盘 A :\n\n");
printf(" \t");
for(i=0;i<=15;i++)//横排辅助坐标
{
printf("%4d ",i+1);
}
printf("\n\n\n\n");
for(i=0;i<=15;i++)
{
printf("%d\t",i+1);//竖排辅助坐标
for(j=0;j<=15;j++)
{
printf("%4d ",board_A[i][j]);
}
printf("\n\n");
}
print_line;
}
void print_board_B()//输出棋盘B
{
int i,j;
void print_line();
printf(" 棋 盘 B :\n\n");
printf(" \t");
for(i=0;i<=15;i++)//横排辅助坐标
{
printf("%4d ",i+1);
}
printf("\n\n\n\n");
for(i=0;i<=15;i++)
{
printf("%d\t",i+1);//竖排辅助坐标
for(j=0;j<=15;j++)
{
printf("%4d ",board_B[i][j]);
}
printf("\n\n");
}
print_line;
}
void print_board_C()//输出棋盘C
{
int i,j;
void print_line();
printf(" 棋 盘 C :\n\n");
printf(" \t");
for(i=0;i<=15;i++)//横排辅助坐标
{
printf("%4d ",i+1);
}
printf("\n\n\n\n");
for(i=0;i<=15;i++)
{
printf("%d\t",i+1);//竖排辅助坐标
for(j=0;j<=15;j++)
{
printf("%4d ",board_C[i][j]);
}
printf("\n\n");
}
print_line;
}
void print_line()
{
printf("\n==================================\n\n");
}
//目的:产生一个0~15的随机数(要在主函数中提前生成随机数种子)
//返回值:一个0~15的随机数
int rand_number()//产生1~100的随机数
{
int num;//num表示0~100的随机数
num=rand()%16;
// printf("随机数是%d\n",num);
return num;
}
//目的:把A板40个0变成1
void mine_initialize()
{
int rand_number();
int mine_total=0;//总雷数(最大40)
int x,y;
for(;mine_total<40;)
{
x=rand_number();
y=rand_number();
if(board_A[x][y]==0)
{
board_A[x][y]=1;
mine_total++;
}
}
}
//目的:由棋盘A计算棋盘B
void calculate_A_to_B()//计算棋盘B
{
int i,j;
for(i=0;i<=15;i++)
{
for(j=0;j<=15;j++)
{
if(board_A[i][j]==1)//如果A板是1,则B板改成88
{
board_B[i][j]=88;
}
else
{
if(i==0&&j==0)//左上角
{
board_B[i][j]=board_A[i+1][j]+board_A[i][j+1]+board_A[i+1][j+1];
}
if(i==0&&j==15)//右上角
{
board_B[i][j]=board_A[i+1][j]+board_A[i][j-1]+board_A[i+1][j-1];
}
if(i==15&&j==0)//左下角
{
board_B[i][j]=board_A[i-1][j]+board_A[i][j+1]+board_A[i-1][j+1];
}
if(i==15&&j==15)//右下角
{
board_B[i][j]=board_A[i-1][j]+board_A[i][j-1]+board_A[i-1][j-1];
}
if(i==0&&j!=0&&j!=15)//上边
{
board_B[i][j]=board_A[i][j+1]+board_A[i][j-1]+board_A[i+1][j]+board_A[i+1][j+1]+board_A[i+1][j-1];
}
if(i==15&&j!=0&&j!=15)//下边
{
board_B[i][j]=board_A[i][j+1]+board_A[i][j-1]+board_A[i-1][j]+board_A[i-1][j+1]+board_A[i-1][j-1];
}
if(j==0&&i!=0&&i!=15)//左边
{
board_B[i][j]=board_A[i+1][j]+board_A[i-1][j]+board_A[i][j+1]+board_A[i+1][j+1]+board_A[i-1][j+1];
}
if(j==15&&i!=0&&i!=15)//右边
{
board_B[i][j]=board_A[i+1][j]+board_A[i-1][j]+board_A[i][j-1]+board_A[i+1][j-1]+board_A[i-1][j-1];
}
if(i!=0&&i!=15&&j!=0&&j!=15)//中间
{
board_B[i][j]=board_A[i+1][j+1]+board_A[i+1][j]+board_A[i+1][j-1]+board_A[i][j+1]+board_A[i][j-1]+board_A[i-1][j+1]+board_A[i-1][j]+board_A[i-1][j-1];
}
}
}
}
}
//目的:点击后展开(从B到C计算)(递归)此函数没有包裹77
//参数:coordinate_x,coordinate_y
//99表示此格在B板中为0
void spread_B_to_C(int coordinate_x,int coordinate_y)//点击后展开
{
if(board_A[coordinate_x][coordinate_y]==0)//如果这个格不是雷
{
if(board_B[coordinate_x][coordinate_y]==0)//如果这个格周围8个没有雷,则这个格在C中显示为99
{
board_C[coordinate_x][coordinate_y]=99; //因为此格在B板中为0
if(board_B[coordinate_x+1][coordinate_y]==0&&coordinate_x+1<=15&&board_C[coordinate_x+1][coordinate_y]!=99)//下
{
board_C[coordinate_x+1][coordinate_y]=99;
spread_B_to_C(coordinate_x+1,coordinate_y);
}
if(board_B[coordinate_x-1][coordinate_y]==0&&coordinate_x-1>=0&&board_C[coordinate_x-1][coordinate_y]!=99)//上
{
board_C[coordinate_x-1][coordinate_y]=99;
spread_B_to_C(coordinate_x-1,coordinate_y);
}
if(board_B[coordinate_x][coordinate_y+1]==0&&coordinate_y+1<=15&&board_C[coordinate_x][coordinate_y+1]!=99)//右
{
board_C[coordinate_x][coordinate_y+1]=99;
spread_B_to_C(coordinate_x,coordinate_y+1);
}
if(board_B[coordinate_x][coordinate_y-1]==0&&coordinate_y-1>=0&&board_A[coordinate_x][coordinate_y-1]!=99)//左
{
board_C[coordinate_x][coordinate_y-1]=99;
spread_B_to_C(coordinate_x,coordinate_y-1);
}
}
if(board_B[coordinate_x][coordinate_y]!=0)//如果这个格周围8个有雷
{
board_C[coordinate_x][coordinate_y]=77;//未来在D中仅显示这一个格
}
}
if(board_A[coordinate_x][coordinate_y]==1)printf("大佬,你踩到雷了!\n");
}
//目的:从C到C的展开(在99外面包裹一层77)
//方法:按顺序查找每一个99,判断其周围8元素在盘C上是否为 0
// 若是0且对应的盘B不是0,则将这个位置变为77
void spread_C_to_C()
{
int i,j;
for(i=0;i<=15;i++)
{
for(j=0;j<=15;j++)
{
if(i==0&&j==0) //左上角 (i+,j+)
{
if(board_C[i][j]==99)
{
if(board_C[i+1][j]==0&&board_B[i+1][j]!=0)
{
board_C[i+1][j]=77;
}
if(board_C[i][j+1]==0&&board_B[i][j+1]!=0)
{
board_C[i][j+1]=77;
}
if(board_C[i+1][j+1]==0&&board_B[i+1][j+1]!=0)
{
board_C[i+1][j+1]=77;
}
}
}
if(i==0&&j==15) //右上角 (i+,j-)
{
if(board_C[i][j]==99)
{
if(board_C[i+1][j]==0&&board_B[i+1][j]!=0)
{
board_C[i+1][j]=77;
}
if(board_C[i][j-1]==0&&board_B[i][j-1]!=0)
{
board_C[i][j-1]=77;
}
if(board_C[i+1][j-1]==0&&board_B[i+1][j-1]!=0)
{
board_C[i+1][j-1]=77;
}
}
}
if(i==15&&j==0) //左下角(i-,j+)
{
if(board_C[i][j]==99)
{
if(board_C[i-1][j]==0&&board_B[i-1][j]!=0)
{
board_C[i-1][j]=77;
}
if(board_C[i][j+1]==0&&board_B[i][j+1]!=0)
{
board_C[i][j+1]=77;
}
if(board_C[i-1][j+1]==0&&board_B[i-1][j+1]!=0)
{
board_C[i-1][j+1]=77;
}
}
}
if(i==15&&j==15) //右下角 (i-,j-)
{
if(board_C[i][j]==99)
{
if(board_C[i-1][j]==0&&board_B[i-1][j]!=0)
{
board_C[i-1][j]=77;
}
if(board_C[i][j-1]==0&&board_B[i][j-1]!=0)
{
board_C[i][j-1]=77;
}
if(board_C[i-1][j-1]==0&&board_B[i-1][j-1]!=0)
{
board_C[i-1][j-1]=77;
}
}
}
if(i==0&&j!=0&&j!=15) //上边(i~ j+-//i+1 j+~-)共5种
{
if(board_C[i][j]==99)
{
if(board_C[i][j+1]==0&&board_B[i][j+1]!=0)
{
board_C[i][j+1]=77;
}
if(board_C[i][j-1]==0&&board_B[i][j-1]!=0)
{
board_C[i][j-1]=77;
}
if(board_C[i+1][j+1]==0&&board_B[i+1][j+1]!=0)
{
board_C[i+1][j+1]=77;
}
if(board_C[i+1][j]==0&&board_B[i+1][j]!=0)
{
board_C[i+1][j]=77;
}
if(board_C[i+1][j-1]==0&&board_B[i+1][j-1]!=0)
{
board_C[i+1][j-1]=77;
}
}
}
if(i==15&&j!=0&&j!=15) //下边 (i~ j+- // i-1 j+~-)
{
if(board_C[i][j]==99)
{
if(board_C[i][j+1]==0&&board_B[i][j+1]!=0)
{
board_C[i][j+1]=77;
}
if(board_C[i][j-1]==0&&board_B[i][j-1]!=0)
{
board_C[i][j-1]=77;
}
if(board_C[i-1][j+1]==0&&board_B[i-1][j+1]!=0)
{
board_C[i-1][j+1]=77;
}
if(board_C[i-1][j]==0&&board_B[i-1][j]!=0)
{
board_C[i-1][j]=77;
}
if(board_C[i-1][j-1]==0&&board_B[i-1][j-1]!=0)
{
board_C[i-1][j-1]=77;
}
}
}
if(j==0&&i!=0&&i!=15) //左边 (j~ i+- // j+1 i+~-)
{
if(board_C[i][j]==99)
{
if(board_C[i+1][j]==0&&board_B[i+1][j]!=0)
{
board_C[i+1][j]=77;
}
if(board_C[i-1][j]==0&&board_B[i-1][j]!=0)
{
board_C[i-1][j]=77;
}
if(board_C[i+1][j+1]==0&&board_B[i+1][j+1]!=0)
{
board_C[i+1][j+1]=77;
}
if(board_C[i][j+1]==0&&board_B[i][j+1]!=0)
{
board_C[i][j+1]=77;
}
if(board_C[i-1][j+1]==0&&board_B[i-1][j+1]!=0)
{
board_C[i-1][j+1]=77;
}
}
}
if(j==15&&i!=0&&i!=15) //右边 (j~ i+- // j-1 i+~-)
{
if(board_C[i][j]==99)
{
if(board_C[i+1][j]==0&&board_B[i+1][j]!=0)
{
board_C[i+1][j]=77;
}
if(board_C[i-1][j]==0&&board_B[i-1][j]!=0)
{
board_C[i-1][j]=77;
}
if(board_C[i+1][j-1]==0&&board_B[i+1][j-1]!=0)
{
board_C[i+1][j-1]=77;
}
if(board_C[i][j-1]==0&&board_B[i][j-1]!=0)
{
board_C[i][j-1]=77;
}
if(board_C[i-1][j-1]==0&&board_B[i-1][j-1]!=0)
{
board_C[i-1][j-1]=77;
}
}
}
if(i!=0&&i!=15&&j!=0&&j!=15) //中间 (9-1
{
if(board_C[i][j]==99)
{
if(board_C[i+1][j+1]==0&&board_B[i+1][j+1]!=0)
{
board_C[i+1][j+1]=77;
}
if(board_C[i+1][j]==0&&board_B[i+1][j]!=0)
{
board_C[i+1][j]=77;
}
if(board_C[i+1][j-1]==0&&board_B[i+1][j-1]!=0)
{
board_C[i+1][j-1]=77;
}
if(board_C[i][j+1]==0&&board_B[i][j+1]!=0)
{
board_C[i][j+1]=77;
}
if(board_C[i][j-1]==0&&board_B[i][j-1]!=0)
{
board_C[i][j-1]=77;
}
if(board_C[i-1][j+1]==0&&board_B[i-1][j+1]!=0)
{
board_C[i-1][j+1]=77;
}
if(board_C[i-1][j]==0&&board_B[i-1][j]!=0)
{
board_C[i-1][j]=77;
}
if(board_C[i-1][j-1]==0&&board_B[i-1][j-1]!=0)
{
board_C[i-1][j-1]=77;
}
}
}
}
}
}
//目的:输入要点击的坐标
//返回值:横坐标和纵坐标
void input_coordinate()
{
printf("如果要标雷,请在坐标前加66,(如:6611 669)\n");
printf("请输入你要点击的坐标,用空格隔开,(如:11 9):");//不用逗号隔开是为了避免用户输入中文逗号;以下为展开过程
printf("\n");
scanf("%d %d",&coordinate_x,&coordinate_y);
coordinate_x--;
coordinate_y--;
if(coordinate_x>60||coordinate_y>60)
{
if(coordinate_x>1000)
{
coordinate_x=coordinate_x-6600;
printf("已标雷1,%d\n",coordinate_x);
}
else if(coordinate_x<1000)
{
coordinate_x=coordinate_x-660;
printf("已标雷2,%d\n",coordinate_x);
}
if(coordinate_y>1000)
{
coordinate_y=coordinate_y-6600;
printf("已标雷3,%d\n",coordinate_y);
}
else if(coordinate_y<1000)
{
coordinate_y=coordinate_y-660;
printf("已标雷4,%d\n",coordinate_y);
}
board_D[coordinate_x][coordinate_y]=666;
printf("标雷成功\n");
}
}
//目的:输出棋盘D
void print_board_D()
{
int i,j;
char char_0=' ';//方便格式输出
char char_c='*';
char char_lei='M';
void print_line();
printf(" 棋 盘 D :\n\n");
printf(" \t");
for(i=0;i<=15;i++)//横排辅助坐标
{
printf("%4d ",i+1);
}
printf("\n\n\n\n");
for(i=0;i<=15;i++)
{
printf("%d\t",i+1);//竖排辅助坐标
for(j=0;j<=15;j++)//这里添加星号:如果盘C是99,则显示0,如果是77,则显示盘B的数,否则显示星号
{
if(board_C[i][j]==99)printf("%4c ",char_0);//如果这个格不是雷,且周围没有雷,输出空格
if(board_C[i][j]==77&&board_A[i][j]!=1)printf("%4d ",board_B[i][j]);//如果这个格将被输出,且本身不是雷,输出周围雷的个数
if(board_C[i][j]==77&&board_A[i][j]==1)printf("%4c ",char_c);//如果这个格将被输出,且本身是雷,输出星号(这种情况不存在,但这行不能删)
if(board_C[i][j]!=77&&board_C[i][j]!=99)
{
if(board_D[i][j]==666)
{
printf("%4c ",char_lei);
}
else printf("%4c ",char_c);//如果这个格不被输出,则输出星号
}
}
printf("\n\n");
}
print_line;
}
//目的:剩余格的个数
//返回值:剩余格的个数
int unknown_num()
{
int unknown=16*16;
int i,j;
for(i=0;i<=15;i++)//数数有多少雷
{
for(j=0;j<=15;j++)
{
if(board_C[i][j]!=0)
{
unknown--;
}
}
}
printf("\n剩余格数:%d\n",unknown);
return unknown;
}