炸弹人 游戏

/*炸弹人
# 代表墙体
.代表可以安放地雷的地方
G代表敌人  地雷会朝着横向竖向炸去 遇到墙体结束
输入起点位置 求可以炸掉最多敌人的坐标
*/
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define H 30//地图尺寸行数
# define L 45//地图尺寸列数
const int NEXT[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//四个用来模拟 向右 向下 向左 向上
char CHO[]={"#..GG"};
char MAP[H][L+1];//用来储存地图的字符数组
char SSS[]={"012345678901234567890123456789012345678901234567890"};
int hh,ll;
int getsum(char MAP[][L+1],int X,int Y);
int gainint(int *p,int a,int b);//输入int *p直至满足(a,b)输入结束,并返回*p  
int main(){
    int queue[H*L][2]={0},head=1,tail=1;//用二维数组模拟队列 quque[0][]储存横坐标 queue[1][]存纵坐标
	int BOOK[H+1][L+1]={0},X,Y,SUM,MAX=0,i,TX,TY,j,k;//BOOK是用来标记的数组 初始化为0 BX BY是begin初始的位置
/****************此处只是生成随机地图可以不看*********************/
	srand(time(NULL));
	printf("输入地图行数∈[4,%d]:",H);
	 gainint(&hh,4,H);
     printf("输入地图宽度∈[6,%d]:",L);
	 gainint(&ll,6,L);
	 SSS[ll]='\0';
	 system("cls");
	for(i=0;i<hh;i++)
	{
		printf("%02d",i);
	   for(j=0;j<ll;j++)
	   {
		   if(i==0&&j==0)
			  printf("%s-------->Y\n00",SSS);
	     if(i==0||i==hh-1||j==0||j==ll-1)
			 MAP[i][j]=CHO[0];
		 else
			 MAP[i][j]=CHO[rand()%5];
		 printf("%c",MAP[i][j]);
	   }
	   printf("\n");
	}
	printf("|\n|\nX\n");
/*********************随机地图生成完毕**************8*/
	do{
		printf("输入起始位置(X,Y):");
		scanf("%d %d",&X,&Y);
		while(getchar()!='\n');
		if(MAP[X][Y]!='.')
			printf("输入位置不空闲,请重新");
	}while(MAP[X][Y]!='.');
	queue[tail][0]=X;     //现将初始坐标压入队列
	queue[tail++][1]=Y;  //
	BOOK[X][Y]=1;          //标记当前已经走过该点
	MAX=getsum(MAP,X,Y); //计算此点的可炸掉的敌人的个数
	while(head<tail)    //当队列不为空时
	{
		for(i=0;i<4;i++)  //枚举四个方向
		{
			TX=queue[head][0]+NEXT[i][0];
			TY=queue[head][1]+NEXT[i][1];
			if(TX<0||TX>hh-1||TY<0||TY>ll-1)  //判断是否出界
				continue;
			if(MAP[TX][TY]=='.'&&!BOOK[TX][TY])//对其判断是否可以安放地雷 并且没走过
			{
				BOOK[TX][TY]=1;    //标记当前已经走过
				queue[tail][0]=TX;   //压入队列
				queue[tail++][1]=TY;
				SUM=getsum(MAP,TX,TY);  //计算此前的可炸掉的敌人数量
				if(SUM>MAX)   //如果炸掉的敌人数量比之前计算得多
				{
					MAX=SUM;   //更新最大值
					X=TX;
					Y=TY;
				}
			}
		}
		head++;    //队头加一进行点的拓展
	}
	system("cls");
	MAP[X][Y]='&';
	for(i=0;i<hh;i++)
	{
		printf("%02d",i);
	   for(j=0;j<ll;j++)
	   {
		   if(i==0&&j==0)
			  printf("%s-------->Y\n00",SSS);
		 printf("%c",MAP[i][j]);
	   }
	   printf("\n");
	}
	printf("|\n|\nX\n");
	printf("炸弹放在(%d,%d)处(地图上标有*的地方) \n最多会消灭%d个敌人.\n",X,Y,MAX);
		return 0;
}
int getsum(char MAP[][L+1],int X,int Y)
{
	int sum=0,xx,yy,i,T[]={-1,1};
	for(i=0;i<4;i++) //四次循环用于计算地雷的总个数
	{
		xx=X;yy=Y;
		while(MAP[xx][yy]!='#') //当没有遇到墙体
		{
			if(MAP[xx][yy]=='G')//如果是敌人
				++sum;
			if(i<2)
				xx+=T[i%2];   //四个方向的判断
			else yy+=T[i%2];
		}
	}
    return sum;     //返回sum
}
int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束,并返回*p      
{       
    do{      
        *p=a-1;    
        scanf("%d",p);      
        while(getchar()!='\n');      
        if(*p>b||*p<a)      
            printf("输入有误,请重新输入(%d--%d):\n",a,b);      
    }while(*p>b||*p<a);      
    return *p;      
} 

附加小程序:

# include <stdio.h>  
# include <string.h>  
# define N 100   //如果想录入x个字节那么就把N的数值改成x   
int gainchar(char *A,int min,int max); 
int gainint(int *p,int a,int b);
void paixu(char *a[],int n,int F); 
void main(){  
    int n,F,i;  
    char B[N][N+1],*P[N],S[][3]={"升","降"};  
    do{  
        printf("输入要录入的字符串个数[2,%d]:",N);
        gainint(&n,2,N);
        for(i=0;i<n;i++)
        {
            printf("第%d个字符串,字节--[1,%d]:",N);
            gainchar(B[i],1,N);
            P[i]=B[i];//让每个指针指向每个字符数组
        }
        printf("升序请按0:降序请按1--[0,1]:");
          gainint(&F,0,1);
        paixu(P,n,F);
        printf("%s后:\n",S[F]);
        for(i=0;i<n;i++)
            printf("%s\n",P[i]);
    }while(1);  
}   
int gainint(int *p,int a,int b)//输入int *p直至满足[a,b]输入结束,返回*p      
{       
    do{      
        *p=a-1;    
        scanf("%d",p);      
        while(getchar()!='\n');      
        if(*p>b||*p<a)      
            printf("输入有误,请重新输入(%d--%d):\n",a,b);      
    }while(*p>b||*p<a);      
    return *p;      
}  
int gainchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度      
{      
    int B,C;    
 do{      
        A[max]=B=C=0;  
        while((A[B++]=getchar())!='\n'&&B<max);  
        if(A[B-1]!='\n')  
            while(getchar()!='\n'&&++C);      
    else A[--B]=0;   
    if(C||B&&B<min)  
       printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);      
    }while(C||B<min);      
    return B;    
}
void paixu(char *a[],int n,int F) 
{  
    int i,j,k,Y;  
    char *temp;
    for(i=0;i<n-1;i++)  
    {  
        k=i;  
        for(j=i+1;j<n;j++)  
        {
            Y=strcmp(a[j],a[k]); 
            if(F?Y<0:Y>0)   //b=0升序  b为其他降序  
                k=j;  
        }
            if(k!=i)  
            {  
                temp=a[k];  
                a[k]=a[i];  
                a[i]=temp;  
            }  
    }  
}  

以上是用字符数组节省交换的时间 

# include <stdio.h>
/*查昊昊:输入字符个数 然后输入字符串 对字符串进行升序或降序排列*/
# define N 101   //如果想录入x个字节那么就把N的数值改成x+1
int gainint(int *p,int a,int b);//返回数字的位数
int gainchar(char *a,int min,int max);//返回字符长度
void paixu(char a[],int n,int b);
void main(){
    int n,c,i,d;
    char B[N],S[][3]={"升","降"};
do{
printf("请输入字符串长度(2--%d):",N-1);
gainint(&n,2,N-1);
printf("输入字符串:\n");
c=gainchar(B,n,n+1);
printf("原字符串:\n%s\n",B);
for(i=0;i<2;i++)
{
printf("%s序:\n",S[i]);
        paixu(B,c,i);
printf("%s\n",B);
}
}while(1);
}
int gainint(int *p,int a,int b)//p相当于地址,在主函数中传入&a,就是把a的地址传到函数里,那么在函数里就可以改变a的值了
{
int c[2]={0,1};
do{
scanf("%d",p);
while(getchar()!='\n');  
if(*p>b||*p<a)
printf("输入有误,请重新输入(%d--%d):",a,b);
}while(*p>b||*p<a);
    return *p;
}
int gainchar(char *a,int min,int max)//对*a输入范围(min,max),如果字符数组中存在'\n',将其改为'\0'
{
int c;
do{
c=-1;
fgets(a,max,stdin);
while(a[++c]);
c=a[c-1]=='\n'&&c<max?c-1:c;
if(c>=max-1)
while(getchar()!='\n');
else
a[c]='\0';
if(c&&(c>max||c<min))//如果用户只输入'\n'则不提示输入错误,否则提示错误
printf("输入有误,请重新输入只录入(%d--%d)字节:\n",min,max-1);
}while(c>max||c<min);
    return c;
}
void paixu(char a[],int n,int b)
{
    int i,j,k,temp;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(b?a[j]>a[k]:a[j]<a[k])   //b=0升序  b为其他降序
k=j;
if(k!=i)
{
temp=a[k];
a[k]=a[i];
a[i]=temp;
}
}
}



  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值