#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;
}
迷宫 填充法新思路(填充干扰路径)
最新推荐文章于 2021-02-16 14:29:31 发布