string progressiveDeepeningSearch(string const initialState, string const goalState, int &numberOfStateExpansions, int maxDepth){
	string path;
	int i=0;
	int c=0;
	int len;
	string strState;
	stack<Puzzle *> Q;
	Puzzle *state;
	Puzzle *nextState;
	state = new Puzzle(initialState, goalState);
	strState=state->toString();
	AddNode(A,strState);
	while(i<500000){
		   i++;	//RLDU   
			if(state->canMoveRight()){
				nextState = state->moveRight();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				AddNode(A,nextState->toString());
				}
			 }
			if(state->canMoveLeft()){
				nextState = state->moveLeft();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				AddNode(A,nextState->toString());
				}
			 }
			if(state->canMoveDown()){
				nextState = state->moveDown();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				AddNode(A,nextState->toString());
				}
			 }
			if(state->canMoveUp()){
				nextState = state->moveUp();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				AddNode(A,nextState->toString());
				}
			 }

		if(Q.empty()){
			 cout<<"no solution"<<endl;
			 break;
		}
	 	 state=Q.top();
	    Q.pop();
		if(state->goalMatch()){
			 len=state->getPathLength();
			 cout<<"have solution and length is : "<<len<<endl;
			 break;
	   }
   }
	path=state->getPath();
	return path;
}
string depthFirstSearch(string const initialState, string const goalState, int &numberOfStateExpansions){
	string path;
	int i=0;
	string strState;
	stack<Puzzle *> Q;
	Puzzle *state;
	Puzzle *nextState;
	state = new Puzzle(initialState, goalState);
	strState=state->toString();
	AddNode(A,strState);
	while(true){
			i++;	//UDLR

		if(state->canMoveDown()){
			nextState = state->moveDown();
			if(Search(A,nextState->toString())==false){
			Q.push(nextState);
			AddNode(A,nextState->toString());
			}
		 }
		if(state->canMoveRight()){
			nextState = state->moveRight();
			if(Search(A,nextState->toString())==false){
			Q.push(nextState);
			AddNode(A,nextState->toString());
			}
		 }
		if(state->canMoveUp()){
			nextState = state->moveUp();
			if(Search(A,nextState->toString())==false){
			Q.push(nextState);
			AddNode(A,nextState->toString());
			}
		 }
		if(state->canMoveLeft()){
			nextState = state->moveLeft();
			if(Search(A,nextState->toString())==false){
			Q.push(nextState);
			AddNode(A,nextState->toString());
			}
		 }
		 state=Q.top();
	    Q.pop();
		 if(state->goalMatch()){
	    break;
	    }
   }
	path=state->getPath();
	return path;
}
Puzzle *Puzzle::moveDown(){
	
	Puzzle *p = new Puzzle(*this);
	
	
   if(y0 < 2){
		
		p->board[y0][x0] = p->board[y0+1][x0];
		p->board[y0+1][x0] = 0;
		
		p->y0++;
		
		p->path = path + "D";
		p->pathLength = pathLength + 1;  
		p->depth = depth + 1;
		
	}
	p->strBoard = p->toString();	
	return p;
	
}
Puzzle *Puzzle::moveUp(){
	
	Puzzle *p = new Puzzle(*this);
	
	
   if(y0 > 0){
		
		p->board[y0][x0] = p->board[y0-1][x0];
		p->board[y0-1][x0] = 0;
		
		p->y0--;
		
		p->path = path + "U";
		p->pathLength = pathLength + 1;  
		p->depth = depth + 1;
		
	}
	p->strBoard = p->toString();
	return p;
	
}
Puzzle *Puzzle::moveLeft(){
	
	Puzzle *p = new Puzzle(*this);
	
	
   if(x0 > 0){
		
		p->board[y0][x0] = p->board[y0][x0-1];
		p->board[y0][x0-1] = 0;
		
		p->x0--;
		
		p->path = path + "L";
		p->pathLength = pathLength + 1;  
		p->depth = depth + 1; //incorrect
		
	}
	p->strBoard = p->toString();
	return p;
	
}
Puzzle *Puzzle::moveRight(){
	
	Puzzle *p = new Puzzle(*this);
	
	
   if(x0 < 2){
		
		p->board[y0][x0] = p->board[y0][x0+1];
		p->board[y0][x0+1] = 0;
		
		p->x0++;
		
		p->path = path + "R";
		p->pathLength = pathLength + 1;  
		p->depth = depth + 1;
		
	}
	
	p->strBoard = p->toString();
	
	return p;
	
}
string A7(string const initialState, string const goalState, int &numberOfStateExpansions, int maxDepth){
	//A* Search with the Strict Expanded List, Heuristic = Sum of Manhattan Distance
	string path;
	int i=0;
	int c=0;
	int len;
	string strState;
	queue<Puzzle *> Q;	//queue
	queue<Puzzle *> Q2;
	Puzzle *state;
	Puzzle *nextState;
	state = new Puzzle(initialState, goalState);
	state->updateHCost(manhattanDistance);
	state->updateFCost();
	strState=state->toString();
	AddNode(A,strState);//Expanded List
	while(i<500000){
		   i++;	//UDLR
			if(state->canMoveUp()){
				nextState = state->moveUp();
				nextState->updateHCost(manhattanDistance);
				nextState->updateFCost();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				//AddNode(A,nextState->toString());
				}
			 }
			if(state->canMoveDown()){
				nextState = state->moveDown();
				nextState->updateHCost(manhattanDistance);
				nextState->updateFCost();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				//AddNode(A,nextState->toString());
				}
			 }
			if(state->canMoveLeft()){
				nextState = state->moveLeft();
				nextState->updateHCost(manhattanDistance);
				nextState->updateFCost();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				//AddNode(A,nextState->toString());
				}
			 }
			if(state->canMoveRight()){
				nextState = state->moveRight();
				nextState->updateHCost(manhattanDistance);
				nextState->updateFCost();
				if(Search(A,nextState->toString())==false&&nextState->getDepth()<=maxDepth){
				Q.push(nextState);
				//AddNode(A,nextState->toString());
				}
			 }
		if(Q.empty()){
			 cout<<"no solution"<<endl;
			 break;
		}
		state=Q.front();
		while(!Q.empty()){
			if(Q.front()->getFCost()<=state->getFCost()){
				state=Q.front();
			}
		Q2.push(Q.front());
		Q.pop();
		}
		while(!Q2.empty()){
			if(Q2.front()!=state){
				Q.push(Q2.front());
				Q2.pop();
			}else{
				Q2.pop();
			}
		}
		AddNode(A,state->toString());
	 	 //state=Q.front();
	    //Q.pop();
		if(state->goalMatch()){
			 len=state->getPathLength();
			 cout<<"have solution and length is : "<<len<<endl;
			 break;
	   }
   }
	path=state->getPath();
	return path;
}