zoukankan      html  css  js  c++  java
  • 迷宫 填充法新思路(填充干扰路径)

    #include<iostream>
    #include<string>
    using namespace std;
    #define n 8
    
    int * filler=new int[n*n];//记录填充位置
    
    int initFiller(){//初始化填充记录器
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			*(filler+n*i+j)=0;
    		}
    	}
    	return 0;
    }
    
    int * createMaze(){//初始化迷宫
    	int i,j;
    	int * a;
    	a=new int[n*n];
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			*(a+n*i+j)=-1;//不设置为0的原因是超过矩阵范围的位置
    		}				//系统默认的是0,会引起麻烦
    	}
    	*(a+n*0+1)=3;
    	*(a+n*1+1)=1;*(a+n*1+2)=1;*(a+n*1+3)=1;*(a+n*1+5)=1;
    	*(a+n*2+3)=1;*(a+n*2+5)=1;*(a+n*2+6)=1;
    	*(a+n*3+1)=1;*(a+n*3+2)=1;*(a+n*3+3)=1;*(a+n*3+4)=1;*(a+n*3+5)=1;
    	*(a+n*4+1)=1;*(a+n*4+4)=1;
    	*(a+n*5+1)=1;*(a+n*5+2)=1;*(a+n*5+4)=1;*(a+n*5+5)=1;*(a+n*5+6)=1;
    	*(a+n*6+2)=1;*(a+n*6+3)=1;*(a+n*6+4)=1;*(a+n*6+6)=1;
    	*(a+n*7+6)=1;
    	return a;
    }
    
    void printMaze(int * a){//打印迷宫
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			if(*(a+n*i+j)==1||*(a+n*i+j)==2){
    				cout<<"  ";
    			}
    			else if(*(a+n*i+j)==3){
    				cout<<"★";
    			}
    			else{//*(a+n*i+j)==-1
    				if(*(filler+n*i+j)==1){//后面变成的-1(填充的位置)
    					cout<<"  ";//后来填充的位置设置为不可见
    				}
    				else{//本来就是-1
    					cout<<"■";
    				}
    			}
    		}
    		cout<<endl;
    	}
    }
    
    int fillInterferePath(int * a){//填充干扰路径
    	int i,j;
    	int * record=new int[n*n];//辅助
    	int flag=0;//设置flag用来推断什么时候终止循环
    	while(flag==0){//用while循环的意义在于通过重复扫描矩阵实现循环填充,以此将所有干扰路径所有填充
    		for(i=0;i<n;i++){
    			for(j=0;j<n;j++){
    				*(record+n*i+j)=*(filler+n*i+j);
    				if(*(a+n*i+j)==1&&*(a+n*i+j-1)==-1&&*(a+n*(i-1)+j)==-1&&*(a+n*(i+1)+j)==-1//为品字形的四个方向
    					||*(a+n*i+j)==1&&*(a+n*i+j-1)==-1&&*(a+n*(i-1)+j)==-1&&*(a+n*i+j+1)==-1
    					||*(a+n*i+j)==1&&*(a+n*i+j+1)==-1&&*(a+n*(i-1)+j)==-1&&*(a+n*(i+1)+j)==-1
    					||*(a+n*i+j)==1&&*(a+n*i+j-1)==-1&&*(a+n*i+j+1)==-1&&*(a+n*(i+1)+j)==-1){
    					*(a+n*i+j)=-1;//将所有品字形路径所有填充,由于这样的路径是死路
    					*(filler+n*i+j)=1;
    				}
    			}
    		}
    		flag=1;//当下面两个for循环不再运行时while循环终止
    		for(i=0;i<n;i++){//意义在于用来推断是否还须要进行填充
    			for(j=0;j<n;j++){
    				if(*(record+n*i+j)!=*(filler+n*i+j)){
    					flag=0;
    				}
    			}
    		}
    	}
    	return 0;
    }
    
    void run(int * a,char ch){
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			if(*(a+n*i+j)==3){
    				switch(ch){
    				case 'w':
    					if(*(a+n*(i-1)+j)==1){//将其限定在通道内
    						*(a+n*i+j)=2;//不走回头路
    						*(a+n*(i-1)+j)=3;
    						return;
    					}
    					else{
    						return;
    					}
    				case 'a':
    					if(*(a+n*i+j-1)==1){
    						*(a+n*i+j)=2;
    						*(a+n*i+j-1)=3;
    						return;
    					}
    					else{
    						return;
    					}
    				case 's':
    					if(*(a+n*(i+1)+j)==1){
    						*(a+n*i+j)=2;
    						*(a+n*(i+1)+j)=3;
    					}
    					else{
    						return;
    					}
    				case 'd':
    					if(*(a+n*i+j+1)==1){
    						*(a+n*i+j)=2;
    						*(a+n*i+j+1)=3;
    						return;
    					}
    					else{
    						return;
    					}
    				default:
    					return;
    				}
    			}
    		}
    	}
    }
    
    char getDirection(int * a){//得到方向
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			if(*(a+n*i+j)==3){
    				if(*(a+n*i+j+1)==1){//*(a+n*(i-1)+j)==1为了将游戏人物限定在通道之内;
    					return 'd';//1为通道,0为障碍物;
    				}
    				else if(*(a+n*(i+1)+j)==1){
    					return 's';
    				}
    				else if(*(a+n*i+j-1)==1){
    					return 'a';
    				}
    				else if(*(a+n*(i-1)+j)==1){
    					return 'w';
    				}
    			}
    		}
    	}
    }
    
    int setFiller(int * a,int * b){//填充前与填充后进行比較(为了设置填充标记)
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			if(*(a+n*i+j)!=*(b+n*i+j)){
    				*(filler+n*i+j)=1;//把进行了填充的位置标记起来
    			}
    		}
    	}
    	return 0;
    }
    
    int * evaluate(int * a){//深拷贝赋值
    	int * b;
    	b=new int[n*n];
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			*(b+n*i+j)=*(a+n*i+j);
    		}
    	}
    	return b;
    }
    
    //仅有用于通道宽度为1的迷宫,若有些迷宫通道宽
    //度大于等于2,该算法有时可能无法处理
    int handle(){
    	int * a, * b;
    	int count=1;
    	string step;//用string是为了避免用户多输入字符而引起错误
    	initFiller();
    	a=createMaze();
    	b=evaluate(a);//把a的值依次赋给b
    	fillInterferePath(a);//填充干扰路径
    	setFiller(a,b);
    	printMaze(a);
    	cout<<"请按随意键进行下一步!"<<endl;
    	while(*(a+n*7+6)!=3){
    		cout<<"第"<<count<<"步:";
    		cin>>step;
    		run(a,getDirection(a));
    		printMaze(a);
    		count++;
    	}
    	cout<<"恭喜你,顺利到达终点!"<<endl;
    	return 0;
    }
    
    int main(){
    	handle();
    	return 0;
    }
    
    

  • 相关阅读:
    settTimeout vs setInterval
    JS继承
    JS创建对象
    原型链
    开始学习python的感受
    Problem 29
    Python 查看关键字
    Problem 21
    Problem 34
    Problem 42
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4220836.html
Copyright © 2011-2022 走看看