#include <queue>
#include <deque>
//
// 배열 내용 값 순서
// 0 1 2
// 3 4 5
// 6 7 8
//
// 찾는 순서
// 0: 왼쪽, 1:위쪽, 2:오른쪽, 3:아래쪽
class Puz
{
public:
enum { MAX_PUZ = 9 };
enum PUZ_DIRECTION { PUZ_LEFT = 0, PUZ_UP, PUZ_RIGHT, PUZ_DOWN, PUZ_DIRECTION_MAX };
Puz()
:m_pParant(NULL), m_nDeep(0)
{
for(int i = 0; i < MAX_PUZ; ++i)
m_nPuz[i] = 0;
for(int i = 0; i < 4; ++i)
m_nNotMove[i] = true;
}
Puz* m_pParant;
int m_nPuz[MAX_PUZ];
int m_nDeep;
bool m_nNotMove[PUZ_DIRECTION_MAX];
void SwapPuz( int _nIndex1, int _nIndex2 )
{
int nTemp = m_nPuz[_nIndex1];
m_nPuz[_nIndex1] = m_nPuz[_nIndex2];
m_nPuz[_nIndex2] = nTemp;
}
bool EqualPuz( Puz* _p )
{
for(int i = 0; i < MAX_PUZ; ++i)
{
if( this->m_nPuz[i] == _p->m_nPuz[i] )
{
}
else
{
return false;
}
}
return true;
}
int SearchZero()
{
for( int i = 0; i < MAX_PUZ; ++i )
{
if( 0 == m_nPuz[i] )
return i;
}
CCLog( "SearchZero() Error!" );
return -1;
}
bool CanMove( int _eVal )
{
switch( _eVal )
{
case PUZ_LEFT:
{
int nZero = SearchZero();
if( 0 == nZero || 3 == nZero || 6 == nZero )
return false;
}
break;
case PUZ_UP:
{
int nZero = SearchZero();
if( 0 == nZero || 1 == nZero || 2 == nZero )
return false;
}
break;
case PUZ_RIGHT:
{
int nZero = SearchZero();
if( 2 == nZero || 5 == nZero || 8 == nZero )
return false;
}
break;
case PUZ_DOWN:
{
int nZero = SearchZero();
if( 6 == nZero || 7 == nZero || 8 == nZero )
return false;
}
break;
}
return m_nNotMove[_eVal];
}
Puz* NodeExpention( int _eVal )
{
Puz* pRt = new Puz;
pRt->m_nDeep = this->m_nDeep + 1;
pRt->m_pParant = this;
for(int i = 0; i < 9; ++i)
pRt->m_nPuz[i] = this->m_nPuz[i];
int nReversal;
switch( _eVal )
{
case PUZ_LEFT:
{
nReversal = PUZ_RIGHT;
break;
}
case PUZ_UP:
{
nReversal = PUZ_DOWN;
break;
}
case PUZ_RIGHT:
{
nReversal = PUZ_LEFT;
break;
}
case PUZ_DOWN:
{
nReversal = PUZ_UP;
break;
}
default:
CCLog("NodeExpention( int _eVal ) Error!");
break;
}
pRt->m_nNotMove[nReversal] = false;
int nZero = SearchZero();
switch( _eVal )
{
case PUZ_LEFT:
{
pRt->SwapPuz(nZero, nZero - 1);
break;
}
case PUZ_UP:
{
pRt->SwapPuz(nZero, nZero - 3);
break;
}
case PUZ_RIGHT:
{
pRt->SwapPuz(nZero, nZero + 1);
break;
}
case PUZ_DOWN:
{
pRt->SwapPuz(nZero, nZero + 3);
break;
}
}
return pRt;
}
};