1. 程式人生 > >泡泡消除最優解

泡泡消除最優解

程式碼只實現了最優解,但是未消除重複,所以比較耗時,有待優化 

 

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