代码只实现了最优解,但是未消除重复,所以比较耗时,有待优化
#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;
}