泡泡消除最优解

代码只实现了最优解,但是未消除重复,所以比较耗时,有待优化 

 

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
#include<stdio.h>
#include<sstream>
#include<ctime>
#include<typeinfo.h>
#include<vector>
#include <cstring>
#define ROW 5
#define COL 5 
using namespace std;
class Point
{
	private:
        int x,y;//坐标
	public:
		Point()
		{
		}
		Point(int x, int y)
		{
			this->x = x;
			this->y = y;
		}
		void setX(int x)
		{
			this->x=x;
		}
		void setY(int y)
		{
			this->y=y;
		}
		int getX()
		{
			return x;
		}
		int getY()
		{
			return y;
		}
		void print()
		{
			cout<<"("<<x<<","<<y<<")"<<endl;
		}
};
class Qipan
{
    private:
    	int score;//保存当前的分
        char pan[ROW][COL];//保存当前盘面
        Point point;//父棋盘点击坐标生成该棋盘
       	// Qipan *parent;//指向父棋盘,用指针出现dfs过程中内存释放,野指针的现象,放弃使用,用以下两点实现指父功能
        int my_pos;//自己在vector (allqipan)的位置
        int parent_pos;//父节点在vector(allqipan) 的位置
    public:
    	Qipan()
    	{
    		score=0;
    		memset(pan,0,sizeof(pan));
    	}
    	void setP(Point p)
    	{
    		point=p;
    	}
    	
      	void setMy_pos(int p)
    	{
    		my_pos=p;
    	}
    	void setParent_pos(int p)
    	{
    		parent_pos=p;
    	}
    	void setPan(int i,int j,char k)
    	{
    		pan[i][j]=k;
    	}
    	void setPan(Point p,char k)
    	{
    		pan[p.getX()][p.getY()]=k;
    	}
    	void setPanfrom(char a[ROW][COL])
    	{
    		int i,j;
    		for(i=0;i<ROW;i++)
    		{
    			for(j=0;j<COL;j++)
    				pan[i][j]=a[i][j];
    		}
    	}
    	void setPanto(char a[ROW][COL])
    	{
    		int i,j;
    		for(i=0;i<ROW;i++)
    		{
    			for(j=0;j<COL;j++)
    				a[i][j]=pan[i][j];
    		}
    	}
    	int getScore()
    	{
    		return score;
    	}
    	void setScore(int n)
    	{
    		score=n;
    	}
    	Point getP()
    	{
    		return point;
    	}
    	char getPan(int i,int j)
    	{
    		return pan[i][j];
    	}
    	char getPan(Point p)
    	{
    		return pan[p.getX()][p.getY()];
    	}
    	int getMy_pos()
    	{
    		return my_pos;
    	}
    	int getParent_pos()
    	{
    		return parent_pos;
    	}
    	void initQipan();//初始化盘面
    	void printQipan();//打印盘面
    	void printInfo();//打印盘面所有信息
    	int calculateScore(int n);//计算消除n个球的得分
    	int eliminate(int x,int y);//消除
    	void findChild();//生产子盘面
};
vector<Qipan> allqipan; //过程中所有的盘面
char pan_temp[ROW][COL];//临时盘面
vector<Qipan> result; //最高得分步骤盘面

int cmp2dArray(char a[ROW][COL],char b[ROW][COL])//判断相同
{
	int i,j;
	for(i=0;i<ROW;i++)
		for(j=0;j<COL;j++)
			if(b[i][j]!=a[i][j])
			{
				return 0;//不同
			}
	return 1;//相同
}

void Qipan::initQipan()
{
	int i,j;
	srand((unsigned)time(NULL));
	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{   
			int tmp = rand()%5;

			switch(tmp)
			{
				case 0:setPan(i,j,'A');
				break;
				case 1:setPan(i,j,'B');
				break;
				case 2:setPan(i,j,'C');
				break;
				case 3:setPan(i,j,'D');
				break;
				case 4:setPan(i,j,'E');
			}
		}
	}
}
void Qipan::printQipan()
{
	int i,j;

	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{  
			cout<<getPan(i,j)<<" ";
		}
		cout<<endl;
	}
}
void Qipan::printInfo()
{
	if(getP().getX()<0||getP().getY()<0)//第一个盘面
	{
		cout<<"初始盘面:"<<endl;
		printQipan();
		cout<<"---------------------------------------"<<endl;
	}
	else
	{
		cout<<"点击坐标:";
		getP().print();
		cout<<"生成盘面:"<<endl;
		printQipan();
		cout<<"当前得分:"<<getScore()<<endl;
		cout<<"---------------------------------------"<<endl;
		
	}
	

}
int Qipan::calculateScore(int n)
{
	int i,j;
	if(n>=2)
	{  
		if(n==2)
			return 2;
		else 
		{ 
			for(i=2,j=2;j<=n;j++)
				i+=(j-2)*2;
			return i;
		}  
	}
	return 0;
}
int dir[4][2] = {0,1,0,-1,1,0,-1,0};
int Qipan::eliminate(int x,int y)
{
	int e_num=1;
	vector<Point> block; 
	Point p(x,y);
	char temp=getPan(p);
	setPan(p,temp+32);
	block.push_back(p);

	while(!block.empty())
	{   
		p= block.back();
		int x=p.getX();
		int y=p.getY();
		block.pop_back();
		
		for(int i = 0; i < 4; i++) {
			int xx = x + dir[i][0];
			int yy = y + dir[i][1];
			if(xx < 0 || xx >= ROW || yy < 0 || yy >= COL) continue;
			if(getPan(xx,yy) != temp) continue;
			p.setX(xx);
			p.setY(yy);
			block.push_back(p);
			setPan(p,temp+32);
			e_num++;
		}
	}
	int i,j,k,col_circle_max=COL,row_circle_max=ROW;

	char bub;
	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{
			if(pan[i][j]>='a')
			{
				pan[i][j]='O';
			}
		}
	}
    //向左边靠拢
	while(col_circle_max--)
	{
		for(i=0;i<ROW;i++)
		{
			for(j=0;j<COL-1;j++)
			{
				if(pan[i][j]=='O')
				{
					bub=pan[i][j];
					pan[i][j]=pan[i][j+1];
					pan[i][j+1]=bub;
				}
			}
		}
	}

    //向上边靠拢
	while(row_circle_max--)
	{
		for(j=0;j<COL;j++)
		{
			for(i=0;i<ROW-1;i++)
			{
				if(pan[i][j]=='O')
				{
					bub=pan[i][j];
					pan[i][j]=pan[i+1][j];
					pan[i+1][j]=bub;
				}
			}
		}
	}
	return e_num;
}
void Qipan::findChild()
{
	int i,j;
	char temp;

	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{  
			Point p(i,j);
			temp=getPan(p);
			if(temp<='E')
			{
				if((i+1<ROW&&getPan(i+1,j)==temp)||(i>0&&getPan(i-1,j)==temp)||(j+1<COL&&getPan(i,j+1)==temp)||(j>0&&getPan(i,j-1)==temp))
				{	
					setPanto(pan_temp);	//暂存未改变的棋盘
					int e_num=eliminate(i,j);
					Qipan child;
					child.setParent_pos(getMy_pos());
					child.setMy_pos(allqipan.size());
					child.setP(p);
					child.setScore(calculateScore(e_num)+getScore());
					
					child.setPanfrom(pan);
					
					setPanfrom(pan_temp);//恢复	

					allqipan.push_back(child);
					child.findChild();	
				}
				else
				{
					continue;
				}
			}
		}

	}
}
int main()
{
	Qipan origin;
	origin.setMy_pos(0);
	origin.setParent_pos(-1);//表示无父
	Point p(-1,-1);
	origin.setP(p);
	origin.initQipan();
	
	allqipan.push_back(origin);
	origin.findChild();
	int max_score=0,index;
	cout<<"\n\n最优解求解过程共生产:"<<allqipan.size()<<"个中间过程棋盘(未消除重复)"<<endl;
	for (int i = 0; i < allqipan.size(); ++i)
	{
		if(allqipan.at(i).getScore()>max_score)
		{
			max_score=allqipan.at(i).getScore();
			index=i;
		}
	}
	cout<<"最高分:"<<max_score<<endl;
	cout<<"\n\n---------------------------------------"<<endl;
	cout<<"---------------------------------------"<<endl;
	Qipan temp=allqipan.at(index);
	
	
	result.push_back(temp);
	
	while(temp.getParent_pos()>=0)
	{
		temp=allqipan.at(temp.getParent_pos());
		result.push_back(temp);

	}
	for (int i = result.size()-1; i >=0; i--) {
		result.at(i).printInfo();
	}
	return 0;
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值