C语言 扫雷小游戏

之前写的扫雷,有一些标雷的小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;
}
	

猜你喜欢

转载自blog.csdn.net/sinat_42483341/article/details/86511636