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

}


};




void main()
{
deque<Puz*> OpenNode;
queue<Puz*> CloseNode;

Puz* InitState = new Puz;
InitState->m_nPuz[0] = 2;
InitState->m_nPuz[1] = 8;
InitState->m_nPuz[2] = 3;
InitState->m_nPuz[3] = 1;
InitState->m_nPuz[4] = 6;
InitState->m_nPuz[5] = 4;
InitState->m_nPuz[6] = 7;
InitState->m_nPuz[7] = 0;
InitState->m_nPuz[8] = 5;

Puz* TargetState = new Puz;
TargetState->m_nPuz[0] = 1;
TargetState->m_nPuz[1] = 2;
TargetState->m_nPuz[2] = 3;
TargetState->m_nPuz[3] = 8;
TargetState->m_nPuz[4] = 0;
TargetState->m_nPuz[5] = 4;
TargetState->m_nPuz[6] = 7;
TargetState->m_nPuz[7] = 6;
TargetState->m_nPuz[8] = 5;

OpenNode.push_front(InitState);

for(;;)
{
if( 0 == OpenNode.size() )
break;

Puz* pNodeN = OpenNode.front();
OpenNode.pop_front();

CloseNode.push( pNodeN );
  
if( 5 > pNodeN->m_nDeep )
{
for(int i = Puz::PUZ_DOWN; i > -1; --i)
{
if( pNodeN->CanMove( i ) )
{
Puz* pDirectionPuz = pNodeN->NodeExpention(i);
if( TargetState->EqualPuz(pDirectionPuz) )
_asm nop // 찾음!
else
OpenNode.push_front(pDirectionPuz); // push_front 대신 push_back 하면 넓이 우선
}
}


} // if( 5 > pNodeN->m_nDeep )
} // for(;;)
}

+ Recent posts