迷宮 填充法新思路(填充干擾路徑)

#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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章