Vous êtes sur la page 1sur 12

#include <cstdlib>

#include <iostream>
#include <cassert>
#include <queue>
#include <stack>
using namespace std;
/*************************************MATRIX CLASS AND DEFINITIONS*
****************************/
class Matrix
{
public:
int tData[4][4];
Matrix()
//Constructor for Input Matrix
{
}
Matrix(int nValue)
//Constructor to Create Final Solution Matrix And Zero Matrix
{
int n=1;
if(nValue==1)
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
//Final Matrix
{
tData[nRow][nCol]=n;
n++;
}
}
tData[3][3]=0;
}
else if (nValue==0)
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
//Zero Matrix
{
tData[nRow][nCol]=0;
}
}
}
else
{
// Set all elements of the matrix
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
cout<<"Row No :"<<nRow<<"\t"<<"Col No :"<<nCol<<"\tTileValue
: "; //User Input Matrix Creation
cin>>tData[nRow][nCol];
cout<<endl;
}
}
}
}
void printmatrix()
//Printing Any Type Of Matrix
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
cout<<tData[nRow][nCol];
cout<<"\t";
}
cout<<endl;
}
}
Matrix(const Matrix &cSource)
//Copy Constructor
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
tData[nRow][nCol]=cSource.tData[nRow][nCol];
}
}
}
int& operator()(const int nCol, const int nRow);
//Assignment Operator Overloaded
Matrix& operator= (const Matrix &cSource);
//Get Address to any spot on Matrix
bool operator==(const Matrix&);
};
Matrix& Matrix::operator= (const Matrix &cSource)
//Assignment Operator Overloaded
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
tData[nRow][nCol]=cSource.tData[nRow][nCol];
}
}
}
int& Matrix::operator()(const int nCol, const int nRow)
//Get Address to any spot on Matrix
{
assert(nCol >= 0 && nCol < 4);
assert(nRow >= 0 && nRow < 4);
return tData[nRow][nCol];
}
void CopyMat(Matrix &mat, Matrix &cMat)
//Copy From one Matrix To Another
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
cMat(nCol,nRow)=mat(nCol,nRow);
}
}
}
void FindBlank(Matrix &Mat,int &row,int &col)
//Find Blank's Row & Col
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if(Mat(nCol,nRow)==0)
{
row=nRow;
col=nCol;
}
}
}
}
bool Matrix::operator==(const Matrix &amat)
//checking if two matrixs are equal or not
{
int count=0;
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if((tData[nRow][nCol])==(amat.tData[nRow][nCol]))
{
count++;
}
}
}
if(count==16)
{
return 1;
}
else
{
return 0;
}
}
int mTiles(Matrix &mat)
//Find Total No. Of Misplaced Tiles
{
Matrix fMat(1);
int count=15;
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if((mat(nCol,nRow)==fMat(nCol,nRow)) && (fMat(nCol,nRow)!=0))
{
count--;
}
}
}
return count;
}
bool checkGoalReached(Matrix &mat)
//Check If the matrix is the Goal State
{
int count=0;
Matrix fMat(1);
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if((mat(nCol,nRow)==fMat(nCol,nRow)))
{
count++;
}
}
}
if(count==16)
{
return 1;
}
else
{
return 0;
}
}
/***************************************NODE STATE AND DEFINITION
S****************************/
class Node
{
public:
Matrix nMat;
static int expanded;
int TpathCost;
//Path Cost
Node *child[4];
int visited[4];
bool goalState;
Node()
//Constructor for root node
{
int bRow,bCol;
//keep blank coordinates
Matrix cMat(0);
//take user input
CopyMat(cMat,nMat);
//copy user input to node matrix
goalState=checkGoalReached(nMat);
//check final goal alread reached
FindBlank(nMat,bRow,bCol);
//find blank coordinates
visit(bRow,bCol);
//setting available movements for blanks
TpathCost=0;
//Intial Path Cost
}
Node(Matrix &Mat,int pathCost)
//Constructor for child node
{
int bRow,bCol;
//keep blank coordinates
CopyMat(Mat,nMat);
//after moving blank the next matrix copy to node matrix
FindBlank(Mat,bRow,bCol);
//find blank coordinates
visit(bRow,bCol);
//setting available movements for blanks
TpathCost=pathCost;
goalState=checkGoalReached(nMat);
//check if goal reached
for(int i=0;i<4;i++)
//setting childs as 0
{
child[i]=0;
}
}

void visit(int row,int col)


{
if(row==0)
{
visited[2]=0;

//cout<<"Cannot Visit Up"<<endl;


}
else
{
visited[2]=1;
//cout<<"Can Visit Up"<<endl;
}
if(col==0)
{
visited[0]=0;
//cout<<"Cannot Visit Left"<<end
l;
}
else
{
visited[0]=1;
//cout<<"Can Visit Left"<<endl;
}
if(col==3)
{
visited[1]=0;
//cout<<"Cannot Visit Right"<<en
dl;
}
else
{
visited[1]=1;
//cout<<"Can Visit Right"<<endl;
}
if(row==3)
{
visited[3]=0;
//cout<<"Cannot Visit Down"<<end
l;
}
else
{
visited[3]=1;
//cout<<"Can Visit Down"<<endl;
}
}
Node& Node::operator= (const Node &cSource);
Node::Node(const Node &cSource);
};
int Node::expanded;
//bool depthLimitedSearch(Node N,int d);
Node::Node(const Node &cSource)
{
nMat=cSource.nMat;
TpathCost=cSource.TpathCost;
for(int i=0;i<4;i++)
{
child[i]=cSource.child[i];
visited[i]=cSource.visited[i];
}
}
Node& Node::operator= (const Node &cSource)
{
nMat=cSource.nMat;
TpathCost=cSource.TpathCost;
for(int i=0;i<4;i++)
{
child[i]=cSource.child[i];
visited[i]=cSource.visited[i];
}
}
Node* createNode(Matrix &Mat,int pathCost,int i)
//Create Node N return itz address
{
Node *N;
N= new Node(Mat,pathCost);
switch(i)
//Direction
{
case 0:
//Left
N->visited[1]=0;
break;
case 1:
//Right
N->visited[0]=0;
break;
case 2:
//Up
N->visited[2]=0;
break;
case 3:
//Down
N->visited[3]=0;
break;
}
return N;
}
Matrix MoveBlank(Node root,int moveDir)
//Moving Blank and Giving new
{
int bRow;
int bCol;
int temp;
int cordtemp;
FindBlank(root.nMat,bRow,bCol);
Matrix Next;
CopyMat(root.nMat,Next);
switch(moveDir)
//Direction
{
case 0:
//Left
cordtemp=bCol-1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(cordtemp,bRow);
Next(cordtemp,bRow)=temp;
break;
case 1:
//Right
cordtemp=bCol+1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(cordtemp,bRow);
Next(bCol+1,bRow)=temp;
break;
case 2:
//Up
cordtemp=bRow-1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(bCol,cordtemp);
Next(bCol,cordtemp)=temp;
break;
case 3:
//Down
cordtemp=bRow+1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(bCol,cordtemp);
Next(bCol,cordtemp)=temp;
break;
}
return Next;
}

/********************************************IDS & DLS**


*********************************/
vector <Node> parent;
bool depthLimitedSearch(Node N,int d)
{
bool goalCheck;
int tempDepth=d;
cout<<endl<<"Depth :"<<d<<endl;
goalCheck=checkGoalReached(N.nMat);
bool alreadyVisited=0;
if (goalCheck)
{
return 1;
}
else
{
if(N.visited[0]==1 && !goalCheck && d>0)
{
tempDepth=d-1;
Matrix nextMat;
if(!parent.empty())
//checking if already present in parent list
{
for(int j=0;j<parent.size();j++)
{
if(parent[j].nMat == nextMat)
{
alreadyVisited=1;
break;
}
else
{
alreadyVisited=0;
}
}
}
nextMat=MoveBlank(N,0);
N.child[0]=createNode(nextMat,N.TpathCost,0);
//creating node allocating space
cout<<endl<<"Moved Left"<<"\tTotal Expanded :"<<Node::expanded<<
endl<<endl;
N.child[0]->nMat.printmatrix();
parent.push_back(*N.child[0]);
//adding to parent list if not present already
if(!alreadyVisited)
{
N.expanded++;
goalCheck=depthLimitedSearch(*N.child[0],tempDepth);
//recursive call to dLs
//system("PAUSE");
}
else
{
return 0;
}
}
else if(N.visited[1]==1 && !goalCheck && d>0)
{
tempDepth=d-1;
Matrix nextMat;
if(!parent.empty())
//checking if already present in parent list
{
for(int j=0;j<parent.size();j++)
{
if(parent[j].nMat == nextMat)
{
alreadyVisited=1;
break;
}
else
{
alreadyVisited=0;
}
}
}
nextMat=MoveBlank(N,1);
N.child[1]=createNode(nextMat,N.TpathCost,1);
cout<<endl<<"Moved Right"<<"\tTotal Expanded :"<<Node::expanded<
<endl<<endl;
N.child[1]->nMat.printmatrix();
parent.push_back(*N.child[1]);

if(!alreadyVisited)
{
N.expanded++;
goalCheck=depthLimitedSearch(*N.child[1],tempDepth);
//recursive call to dLs
//system("PAUSE");
}
else
{
return 0;
}
}
else if(N.visited[2]==1 && !goalCheck && d>0)
{
tempDepth=d-1;
Matrix nextMat;
if(!parent.empty())
//checking if already present in parent list
{
for(int j=0;j<parent.size();j++)
{
if(parent[j].nMat == nextMat)
{
alreadyVisited=1;
break;
}
else
{
alreadyVisited=0;
}
}
}
nextMat=MoveBlank(N,2);
N.child[2]=createNode(nextMat,N.TpathCost,2);
cout<<endl<<"Moved Up"<<"\tTotal Expanded :"<<Node::expanded<<en
dl<<endl;
N.child[2]->nMat.printmatrix();
parent.push_back(*N.child[2]);

if(!alreadyVisited)
{
N.expanded++;
goalCheck=depthLimitedSearch(*N.child[2],tempDepth);
//recursive call to dLs
//system("PAUSE");
}
else
{
return 0;
}
}
else if(N.visited[3]==1 && !goalCheck && d>0)
{
tempDepth=d-1;
Matrix nextMat;
if(!parent.empty())
//checking if already present in parent list
{
for(int j=0;j<parent.size();j++)
{
if(parent[j].nMat == nextMat)
{
alreadyVisited=1;
break;
}
else
{
alreadyVisited=0;
}
}
}
nextMat=MoveBlank(N,3);
N.child[3]=createNode(nextMat,N.TpathCost,3);
cout<<endl<<"Moved Down"<<"\tTotal Expanded :"<<Node::expanded<<
endl<<endl;
N.child[3]->nMat.printmatrix();
parent.push_back(*N.child[3]);
if(!alreadyVisited)
{
N.expanded++;
goalCheck=depthLimitedSearch(*N.child[3],tempDepth);
//recursive call to dLs
//system("PAUSE");
}
else
{
return 0;
}

}
else
{
return 0;
}
}
if( goalCheck == 0) return 0;
else if (goalCheck == 1) return 1;
else return 0;
}
bool IDS(Node &root)
{
int depth;
bool result;
result=0;
Node::expanded=1;
for(depth=1; depth<=320; depth++)
{
cout<<"/********************Depth Limit :"<<depth<<"*******************
/"<<endl;
result = depthLimitedSearch(root,depth);
system("PAUSE");
cout<<endl<<endl;
if(result)
{
break;
}
}
return result;
}

int main(int argc, char *argv[])


{
Matrix nMat(3);
Node root(nMat,0);
bool result;
result=0;
result=IDS(root);
if(result)
{
cout<<endl<<"Final State Reached"<<endl;
cout<<"Total Number of Nodes Expanded :"<<root.expanded<<endl;
}
else
{
cout<<endl<<"Couldn't Reach Final State"<<endl;
}
cout<<endl<<endl<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}

Vous aimerez peut-être aussi