华容道(huarongdao)C++ BFS求解

用C++编了个解传统益智游戏华容道的程序,不到1s可给出横刀立马通关步骤。主要用到bfs加上记录已遇到的局面(包括其对称的局面)帮助剪枝。简单修改初始化可解其它初始排布下的华容道。

 上图即为横刀立马开局

#include <bits/stdc++.h>
using namespace std;

const int M=5,N=4;
const int caocao_qzIdx=1;
const string NAME[10]={"张飞","曹操","马超","黄忠","关羽","赵云","兵","兵","兵","兵"};
string templateStrMap="";
inline int e(int i,int j)
{
	return i*N+j;
}
struct QZ{
	int m=1,n=1;
	int i=0,j=0;
	int type=1,id=0;
	string name;
	QZ()
	{
	}
	QZ(int _m,int _n,int _i,int _j,int _id=0)
	{
		m=_m;
		n=_n;
		i=_i;
		j=_j;
		if(m==1)
		{
			if(n==1)
				type=1;
			else
				type=3;
		}
		else
		{
			if(n==1)
				type=2;
			else
				type=4;
		}
		id=_id;
		name=NAME[id];
	}
	void set(int _m,int _n,int _i,int _j)
	{
		m=_m;
		n=_n;
		i=_i;
		j=_j;
		if(m==1)
		{
			if(n==1)
				type=1;
			else
				type=3;
		}
		else
		{
			if(n==1)
				type=2;
			else
				type=4;
		}
	}
};
struct Move{
	int qzIdx,dir;
	string lastStrMap;
	vector<QZ> lastQZs;
};
map<string,Move> path;
void print(int Map[M][N])
{
			for(int i=0;i<M;i++)
		{
		
			for(int j=0;j<N;j++)
			{
				cout<<Map[i][j]<<" ";
			}
			cout<<endl;
		}
	cout<<endl;
}
void print(vector<QZ> &QZs)
{
	for(int i=0;i<QZs.size();i++)
	{
		QZ &tmp=QZs[i];
		cout<<"i,j:"<<tmp.i<<","<<tmp.j<<" m,n:"<<tmp.m<<","<<tmp.n<<" "<<tmp.type<<endl;
	}
}
void print(string &s)
{
	for(int i=0;i<M;i++)
	{
		for(int j=0;j<N;j++)
		{
			cout<<int(s[e(i,j)])<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
}
struct MAP{
	//int Map[M][N]={{2,4,4,2},{2,4,4,2},{2,3,3,2},{2,1,1,2},{1,0,0,1}};//0为空,1为1*1的兵,2为2*1的武将,3为1*2的武将,4为2*2的曹操
	string strMap="2442;2442;2332;2112;1001";
	vector<QZ> QZs;
	int d=0;
	MAP()
	{
		QZs.push_back(QZ(2,1,0,0,0));
		QZs.push_back(QZ(2,2,0,1,1));
		QZs.push_back(QZ(2,1,0,3,2));
		QZs.push_back(QZ(2,1,2,0,3));
		QZs.push_back(QZ(1,2,2,1,4));
		QZs.push_back(QZ(2,1,2,3,5));
		QZs.push_back(QZ(1,1,3,1,6));
		QZs.push_back(QZ(1,1,3,2,7));
		QZs.push_back(QZ(1,1,4,0,8));
		QZs.push_back(QZ(1,1,4,3,9));
	}
	MAP(string &s,vector<QZ> &_QZs,int _d=0)
	{
		strMap=s;
		QZs=_QZs;
		d=_d; 
	}

	void testQZs()
	{
		int map1[M][N]={0};
		for(int i=0;i<QZs.size();i++)
		{
			QZ &temp=QZs[i];
			for(int I=0;I<temp.m;I++)
				for(int J=0;J<temp.n;J++)
					map1[temp.i+I][temp.j+J]=temp.m+0.1*temp.n;
		}
		print(map1);
	}
	//0为左,1为上,2为右,3为下 
	bool ifmove(int QZ_idx,int dir)
	{
		QZ &temp=QZs[QZ_idx];
		int i=temp.i,j=temp.j,m=temp.m,n=temp.n;
		//cout<<"ifmove:"<<i<<" "<<j<<" "<<dir<<endl;
		if(dir==0)
		{
			if(j>0&&strMap[e(i,j-1)]==0)
			{
				if(temp.m==1||strMap[e(i+1,j-1)]==0)
					return true;
			}
		}
		else if(dir==1)
		{
			if(i>0&&strMap[e(i-1,j)]==0)
			{
				if(temp.n==1||strMap[e(i-1,j+1)]==0)
					return true;
			}
		}
		else if(dir==2)
		{
			if(m==1)
			{
				if(n==1)
				{
					if(j+1<N&&strMap[e(i,j+1)]==0)
						return true;
				}
				else
				{
					if(j+2<N&&strMap[e(i,j+2)]==0)
						return true;
				}
			}
			else
			{
				if(n==1)
				{
					if(j+1<N&&strMap[e(i,j+1)]==0&&strMap[e(i+1,j+1)]==0)
						return true;
				}
				else
				{
					if(j+2<N&&strMap[e(i,j+2)]==0&&strMap[e(i+1,j+2)]==0)
						return true;
				}
			}
		}
		else
		{
			if(m==1)
			{
				if(n==1)
				{
					if(i+1<M&&strMap[e(i+1,j)]==0)
						return true;
				}
				else
				{
					if(i+1<M&&strMap[e(i+1,j)]==0&&strMap[e(i+1,j+1)]==0)
						return true;
				}
			}
			else
			{
				if(n==1)
				{
					if(i+2<M&&strMap[e(i+2,j)]==0)
						return true;
				}
				else
				{
					if(i+2<M&&strMap[e(i+2,j)]==0&&strMap[e(i+2,j+1)]==0)
						return true;
				}
			}
		}
		return false;
	}
	void move(int QZ_idx,int dir)
	{
		QZ &temp=QZs[QZ_idx];
		string &tmpMap=strMap;
		for(int i=0;i<temp.m;i++)
			for(int j=0;j<temp.n;j++)
			{
				int I=temp.i+i,J=temp.j+j;
				tmpMap[e(I,J)]=0;
			}
		for(int i=0;i<temp.m;i++)
			for(int j=0;j<temp.n;j++)
			{
				int I=temp.i+i,J=temp.j+j;
				if(dir==0)
				{
					tmpMap[e(I,J-1)]=temp.type;

				}
				else if(dir==1)
				{
					tmpMap[e(I-1,J)]=temp.type;

				}
				else if(dir==2)
				{
					tmpMap[e(I,J+1)]=temp.type;

				}
				else
				{
					tmpMap[e(I+1,J)]=temp.type;
				}
			}
		if(dir==0)
				{
					temp.j--;

				}
				else if(dir==1)
				{
					temp.i--;

				}
				else if(dir==2)
				{
					temp.j++;

				}
				else
				{
					temp.i++;
				}
		
	}
	string move2string(int QZ_idx,int dir)
	{
		QZ &temp=QZs[QZ_idx];
		string tmpMap=strMap;
		for(int i=0;i<temp.m;i++)
			for(int j=0;j<temp.n;j++)
			{
				int I=temp.i+i,J=temp.j+j;
				tmpMap[e(I,J)]=0;
			}
			for(int i=0;i<temp.m;i++)
			for(int j=0;j<temp.n;j++)
			{
				int I=temp.i+i,J=temp.j+j;
				if(dir==0)
				{
					tmpMap[e(I,J-1)]=temp.type;

				}
				else if(dir==1)
				{
					tmpMap[e(I-1,J)]=temp.type;

				}
				else if(dir==2)
				{
					tmpMap[e(I,J+1)]=temp.type;

				}
				else
				{
					tmpMap[e(I+1,J)]=temp.type;
				}
			}
			//cout<<"finish"<<endl;
			return tmpMap;
		
	}
//	string genString()
//	{
//		string s="";
//		for(int i=0;i<M;i++)
//		{
//			for(int j=0;j<N;j++)
//			{
//				s+=to_string(int(Map[i][j]));
//			}
//			s+=";";
//		}
//		return s;
//	}
	string genString(int _Map[M][N])
	{
		string s="";
		for(int i=0;i<M;i++)
		{
			for(int j=0;j<N;j++)
			{
				s+=int(_Map[i][j]);
			}
		}
		//cout<<"s finish"<<endl;
		return s;
	}
	void genMap(string &s)
	{
		int Map[M][N]={0};
		for(int i=0;i<M;i++)
			for(int j=0;j<N;j++)
			{
				int idx=i*N+j;
				Map[i][j]=s[idx];
			}
	}
//	void genQZs()
//	{
//		int tmpMap[M][N];
//		memcpy(tmpMap,Map,sizeof(Map));
//		int I=0;
//		for(int i=0;i<M;i++)
//			for(int j=0;j<N;j++)
//			{
//				if(tmpMap[i][j]==2)
//				{
//					tmpMap[i+1][j]=-2;
//					QZs[I++].set(2,1,i,j);
//				}
//				else if(tmpMap[i][j]==4)
//				{
//					tmpMap[i][j+1]=-4;
//					tmpMap[i+1][j+1]=-4;
//					tmpMap[i+1][j]=-4;
//					QZs[I++].set(2,2,i,j);
//					caocao_qzIdx=I-1;
//				}
//				else if(tmpMap[i][j]==3)
//				{
//					tmpMap[i][j+1]=-3;
//					QZs[I++].set(1,2,i,j);
//				}
//				else if(tmpMap[i][j]==1)
//				{
//					QZs[I++].set(1,1,i,j);
//				}
//			}
//	}
	bool ifEnd()
	{
		QZ &temp=QZs[caocao_qzIdx];
		if(temp.i==3&&temp.j==1)
			return true;
		return false;
	}
}mymap;

string mirror(string &s)
{
	string s1=s;
	for(int i=0;i<M;i++)
		for(int j=0;j<N;j++)
		{
			s1[e(i,N-j-1)]=s[e(i,j)];
		}
	return s1;
}
string genResStr(vector<QZ> &QZs)
{
	string s=templateStrMap;
	for(int I=0;I<QZs.size();I++)
	{
		QZ &q=QZs[I];
		int i=q.i,j=q.j;
		if(q.type==1)
		{
			s.replace(i*(2*N+1)+2*j,2,"兵"); 
		}
		else if(q.type==2)
		{
			s.replace(i*(2*N+1)+2*j,2,q.name.substr(0,2)); 
			s.replace((i+1)*(2*N+1)+2*j,2,q.name.substr(2,2)); 
		}
		else if(q.type==3)
		{
			s.replace(i*(2*N+1)+2*j,2,q.name.substr(0,2)); 
			s.replace(i*(2*N+1)+2*(j+1),2,q.name.substr(2,2)); 
		}
		else
		{
			s.replace(i*(2*N+1)+2*j,4,q.name); 
			s.replace((i+1)*(2*N+1)+2*j,4,q.name); 
		}
	}
	return s;
}
void writeRes(vector<Move> &resPath)
{
	ofstream wr;
	wr.open("hrd_out.txt",ios::app);
	for(int i=resPath.size()-1;i>=0;i--)
	{
		Move &m=resPath[i];
		for(int i=0;i<M;i++)
		{
			for(int j=0;j<N;j++)
			{
				
			}
			wr<<endl;
		}
	}
} 
string bfs()
{
	queue<MAP> q;
	q.push(mymap);
	unordered_set<string> visited;
	visited.insert(mymap.strMap);
	int D=0;
	while(!q.empty())
	{
		MAP tmpNode=q.front();
		string &s0=tmpNode.strMap;
		//print(s0);
		vector<QZ> &QZs=tmpNode.QZs;
		//print(QZs);
		int d=tmpNode.d;
		q.pop();
		if(d>D)
		{
			D=d;
			cout<<d<<endl;
		}
		if(tmpNode.ifEnd())
		{
			return s0;
		}
		for(int i=0;i<QZs.size();i++)
		{
			QZ &temp=QZs[i];
			//cout<<"i="<<i<<endl;
			for(int dir=0;dir<4;dir++)
			{
				//cout<<"dir"<<dir<<endl;
				if(tmpNode.ifmove(i,dir))
				{
					//cout<<temp.i<<" "<<temp.j<<" "<<dir<<endl;
					//mymap.move(i,dir);
					string s1=tmpNode.move2string(i,dir);
					//cout<<"next"<<endl;
					if(!visited.count(s1))
					{
						//cout<<"next0"<<endl;
						visited.insert(s1);
						visited.insert(mirror(s1));
						path[s1]={i,dir,s0,QZs};
						MAP map1(s1,QZs,d+1);
						QZ &temp1=map1.QZs[i]; 
						if(dir==0)
						{
							temp1.j--;
		
						}
						else if(dir==1)
						{
							temp1.i--;
		
						}
						else if(dir==2)
						{
							temp1.j++;
		
						}
						else
						{
							temp1.i++;
						}
						if(map1.ifEnd())
						{
							return s1;
						}
						q.push(map1);
						//cout<<s1<<endl;
						//cout<<"next1"<<endl;
					}

				}
			}
		}
	}
}



int main()
{
	
	cout<<"huarongdao"<<endl;
	//mymap.testQZs();
	int Map[M][N]={{2,4,4,2},{2,4,4,2},{2,3,3,2},{2,1,1,2},{1,0,0,1}};
	for(int i=0;i<M;i++)
	{
		for(int j=0;j<N;j++)
		{ 
			mymap.strMap[e(i,j)]=Map[i][j];
			templateStrMap+="  ";
		} 
		templateStrMap+="\n";
	}
	//string s1="2442;2442;2332;2112;0110";
	//mymap.strMap=s1;
	//mymap.genMap(mymap.strMap);
	//mymap.genQZs();
	print(mymap.strMap);
	cout<<endl;
	cout<<templateStrMap;
	cout<<genResStr(mymap.QZs)<<endl; 
//	for(int I=0;I<2;I++)
//	for(int i=0;i<mymap.QZs.size();i++)
//	{
//		QZ &temp=mymap.QZs[i];
//		for(int dir=0;dir<4;dir++)
//		{
//		
//		if(mymap.ifmove(i,dir))
//		{
//		cout<<temp.i<<" "<<temp.j<<" "<<dir<<endl;
//			mymap.move(i,dir);
//			
//			print(mymap.strMap);
//			print(mymap.QZs);
//			cout<<endl;
//		}
//	}
//	}
	string s=bfs();
	print(s);
	vector<Move> resPath;
	while(path.count(s))
	{
		resPath.push_back(path[s]);
		s=path[s].lastStrMap;
	} 
	for(int i=resPath.size()-1;i>=0;i--)
	{
		cout<<genResStr(resPath[i].lastQZs)<<endl;
	}
	return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值