void BarycentricMapperMeshTopology<CudaVec3fTypes,CudaVec3fTypes>::applyJT( In::MatrixDeriv& out, const Out::MatrixDeriv& in)
{

    Out::MatrixDeriv::RowConstIterator rowItEnd = in.end();

    for ( Out::MatrixDeriv::RowConstIterator rowIt = in.begin(); rowIt != rowItEnd; ++rowIt)
    {
        Out::MatrixDeriv::ColConstIterator colItEnd = rowIt.end();
        Out::MatrixDeriv::ColConstIterator colIt = rowIt.begin();

        int indexIn;

        if (colIt != colItEnd)
        {
            In::MatrixDeriv::RowIterator o = out.writeLine(rowIt.index());
            for ( ; colIt != colItEnd; ++colIt)
            {
                indexIn = colIt.index();
                InDeriv data = (InDeriv) colIt.val();

                for (int j=0; j<maxNIn; ++j)
                {
                    const OutReal f = ( OutReal ) getMapValue(indexIn,j);
                    int index = getMapIndex(indexIn,j);
                    if (index < 0) break;
                    o.addCol( index, data * f );
                }

            }
        }
    }
}
Beispiel #2
0
bool AflMapData::setMapSize(INT iWidth,INT iHeight)
{
	int i,j,k;
	for(i=0;i<5;i++)
	{
		PSHORT pData = NEW SHORT[iWidth*iHeight];
		ZeroMemory(pData,sizeof(SHORT)*iWidth*iHeight);
		for(j=0;j < iHeight ;j++)
		{
			for(k=0;k < iWidth ;k++)
				pData[iWidth*j+k] = getMapIndex(i,k,j);
		}

    	std::auto_ptr<SHORT> sData(pData);
		m_ptrData[i] = sData;
	}

	m_iMapWidth = iWidth;
	m_iMapHeight = iHeight;
	return true;
}
void Pacman::moveEntity(unsigned int* cellIndex, sf::Vector2f* offset, ViewDirection* direction, ViewDirection* desiredDirection, bool* isMoving, float speed, bool isPlayer)
{
	// Si está quieto, modificamos su dirección directamente
	if(!*isMoving && *direction != *desiredDirection)
	{
		*direction = *desiredDirection;
	}

	*isMoving = true;

	// Modificamos su dirección si es posible y movemos el objeto resolviendo colisiones
	if(*direction == ViewDirection::Left)
	{
		if(*desiredDirection != *direction && !checkCollision(*cellIndex, *desiredDirection, isPlayer))
		{
			switch(*desiredDirection)
			{
				case ViewDirection::Right:
					*direction = *desiredDirection;
					break;
				case ViewDirection::Up:
				case ViewDirection::Down:
					if(offset->x >= 0 && (offset->x + speed) >= 0)
					{
						offset->x = 0;
						*direction = *desiredDirection;

						return;
					}
					break;
				default:
					break;
			}
		}

		if(offset->x <= 0 && checkCollision(*cellIndex, *direction, isPlayer))
		{
			*isMoving = false;
			*desiredDirection = *direction;
			offset->x = 0;

			return;
		}

		offset->x -= speed;

		if(offset->x < -(m_tileSize.x / 2))
		{
			*cellIndex = getMapIndex(*cellIndex, ViewDirection::Left);

			offset->x = (m_tileSize.x / 2) - abs((m_tileSize.x / 2) + offset->x);
		}
	}
	else if(*direction == ViewDirection::Right)
	{
		if(*desiredDirection != *direction && !checkCollision(*cellIndex, *desiredDirection, isPlayer))
		{
			switch(*desiredDirection)
			{
				case ViewDirection::Left:
					*direction = *desiredDirection;
					break;
				case ViewDirection::Up:
				case ViewDirection::Down:
					if(offset->x <= 0 && (offset->x - speed) <= 0)
					{
						offset->x = 0;
						*direction = *desiredDirection;

						return;
					}
					break;
				default:
					break;
			}
		}

		if(offset->x >= 0 && checkCollision(*cellIndex, *direction, isPlayer))
		{
			*isMoving = false;
			*desiredDirection = *direction;
			offset->x = 0;

			return;
		}

		offset->x += speed;

		if(offset->x > (m_tileSize.x / 2))
		{
			*cellIndex = getMapIndex(*cellIndex, ViewDirection::Right);

			offset->x = -(m_tileSize.x / 2) + abs((m_tileSize.x / 2) - offset->x);
		}
	}
	else if(*direction == ViewDirection::Up)
	{
		if(*desiredDirection != *direction && !checkCollision(*cellIndex, *desiredDirection, isPlayer))
		{
			switch(*desiredDirection)
			{
				case ViewDirection::Down:
					*direction = *desiredDirection;
					break;
				case ViewDirection::Left:
				case ViewDirection::Right:
					if(offset->y >= 0 && (offset->y + speed) >= 0)
					{
						offset->y = 0;
						*direction = *desiredDirection;

						return;
					}
					break;
				default:
					break;
			}
		}

		if(offset->y <= 0 && checkCollision(*cellIndex, *direction, isPlayer))
		{
			*isMoving = false;
			*desiredDirection = *direction;
			offset->y = 0;

			return;
		}

		offset->y -= speed;

		if(offset->y < -(m_tileSize.y / 2))
		{
			*cellIndex = getMapIndex(*cellIndex, ViewDirection::Up);

			offset->y = (m_tileSize.y / 2) - abs((m_tileSize.y / 2) + offset->y);
		}
	}
	else if(*direction == ViewDirection::Down)
	{
		if(*desiredDirection != *direction && !checkCollision(*cellIndex, *desiredDirection, isPlayer))
		{
			switch(*desiredDirection)
			{
				case ViewDirection::Up:
					*direction = *desiredDirection;
					break;
				case ViewDirection::Left:
				case ViewDirection::Right:
					if(offset->y <= 0 && (offset->y - speed) <= 0)
					{
						offset->y = 0;
						*direction = *desiredDirection;

						return;
					}
					break;
				default:
					break;
			}
		}

		if(offset->y >= 0 && checkCollision(*cellIndex, *direction, isPlayer))
		{
			*isMoving = false;
			*desiredDirection = *direction;
			offset->y = 0;

			return;
		}

		offset->y += speed;

		if(offset->y > (m_tileSize.y / 2))
		{
			*cellIndex = getMapIndex(*cellIndex, ViewDirection::Down);

			offset->y = -(m_tileSize.y / 2) + abs((m_tileSize.y / 2) - offset->y);
		}
	}
}
unsigned int Pacman::getMapInfo(unsigned int cellIndex, ViewDirection direction)
{
	return m_mapInfo[getMapIndex(cellIndex, direction)];
}
Pacman::ViewDirection Pacman::getRandomDirection(unsigned int cellIndex, unsigned int ignoreCell)
{
	std::vector<ViewDirection> randomDirection;
	ViewDirection ignoreDirection = ViewDirection::Up; // Inicializamos su valor para que no se queje el compilador

	if(ignoreCell != m_mapNullCell)
	{
		if(ignoreCell == getMapIndex(cellIndex, ViewDirection::Right))
		{
			ignoreDirection = ViewDirection::Right;
		}
		else if(ignoreCell == getMapIndex(cellIndex, ViewDirection::Left))
		{
			ignoreDirection = ViewDirection::Left;
		}
		else if(ignoreCell == getMapIndex(cellIndex, ViewDirection::Down))
		{
			ignoreDirection = ViewDirection::Down;
		}
		else
		{
			ignoreDirection = ViewDirection::Up;
		}

		if(getMapInfo(cellIndex, ViewDirection::Right) != CellType::Wall)
		{
			if(ignoreDirection != ViewDirection::Right)
			{
				randomDirection.push_back(ViewDirection::Right);
			}
		}

		if(getMapInfo(cellIndex, ViewDirection::Left) != CellType::Wall)
		{
			if(ignoreDirection != ViewDirection::Left)
			{
				randomDirection.push_back(ViewDirection::Left);
			}
		}

		if(getMapInfo(cellIndex, ViewDirection::Up) != CellType::Wall)
		{
			if(ignoreDirection != ViewDirection::Up)
			{
				randomDirection.push_back(ViewDirection::Up);
			}
		}

		if(getMapInfo(cellIndex, ViewDirection::Down) != CellType::Wall)
		{
			if(ignoreDirection != ViewDirection::Down)
			{
				randomDirection.push_back(ViewDirection::Down);
			}
		}
	}
	else
	{
		if(getMapInfo(cellIndex, ViewDirection::Right) != CellType::Wall)
		{
			randomDirection.push_back(ViewDirection::Right);
		}

		if(getMapInfo(cellIndex, ViewDirection::Left) != CellType::Wall)
		{
			randomDirection.push_back(ViewDirection::Left);
		}

		if(getMapInfo(cellIndex, ViewDirection::Up) != CellType::Wall)
		{
			randomDirection.push_back(ViewDirection::Up);
		}

		if(getMapInfo(cellIndex, ViewDirection::Down) != CellType::Wall)
		{
			randomDirection.push_back(ViewDirection::Down);
		}
	}

	if(randomDirection.empty())
	{
		return ignoreDirection;
	}
	else
	{
		return randomDirection[rand() % randomDirection.size()];
	}
}
void Pacman::onTick()
{
	// Cambiar dirección deseada de Pacman
	if(m_input->getKeyPress()->Up.value)
	{
		m_player.DesiredDirection = ViewDirection::Up;
	}
	else if(m_input->getKeyPress()->Right.value)
	{
		m_player.DesiredDirection = ViewDirection::Right;
	}
	else if(m_input->getKeyPress()->Left.value)
	{
		m_player.DesiredDirection = ViewDirection::Left;
	}
	else if(m_input->getKeyPress()->Down.value)
	{
		m_player.DesiredDirection = ViewDirection::Down;
	}

	if(m_readyTimer.getTicks() > 0)
	{
		if(m_readyTimer.getTicks() >= 2000)
		{
			m_readyTimer.stop();
			m_gameTimer.start();
			m_frameTimer.start();
		}

		return;
	}

	if(m_pauseTimer.getTicks() > 0)
	{
		if(m_pauseTimer.getTicks() >= 500)
		{
			m_pauseTimer.stop();

			m_gameTimer.resume();
			m_frameTimer.resume();
			if(m_ghostKillTimer.isPaused())
			{
				m_ghostKillTimer.resume();
			}

			if(m_player.IsDead)
			{
				resetGame();
			}
		}

		return;
	}

	// Animar Pacman y Fantasmas (Cambio de Frames)
	if(m_frameTimer.getTicks() > 50)
	{
		if(m_player.Moving)
		{
			m_player.CurrentFrame++;

			if(m_player.CurrentFrame > 3)
			{
				m_player.CurrentFrame = 0;
			}
		}
		else
		{
			m_player.CurrentFrame = 1;
		}

		for(unsigned int x = 0; x < m_ghostCount; ++x)
		{
			m_ghost[x].CurrentFrame++;

			if(m_ghost[x].CurrentFrame > 1)
			{
				m_ghost[x].CurrentFrame = 0;
			}
		}

		m_frameTimer.start();
	}

	// Mover Pacman
	moveEntity(&m_player.CurrentCellIndex, &m_player.PositionOffset, &m_player.Direction, &m_player.DesiredDirection, &m_player.Moving, m_player.MoveSpeed, true);

	bool ghostForceRefresh = false;

	sf::Vector2i findCoin = sf::Vector2i(m_player.CurrentCellIndex % m_mapSize.x, floor(m_player.CurrentCellIndex / m_mapSize.x));

	// Comer bolas (Pacman) y actualizar mapa
	for(unsigned int x = 0; x < m_ballPosition.size(); ++x)
	{
		if(m_ballPosition[x] == findCoin)
		{
			mapSetCell(m_player.CurrentCellIndex, CellType::Nothing);

			m_ballPosition.erase(m_ballPosition.begin() + x);

			addScore(10);

			m_sound.setBuffer(m_ballSound);
			m_sound.play();

			if(m_ballPosition.empty() && m_ballBigPosition.empty())
			{
				resetGame();

				return;
			}
		}
	}

	for(unsigned int x = 0; x < m_ballBigPosition.size(); ++x)
	{
		if(m_ballBigPosition[x] == findCoin)
		{
			mapSetCell(m_player.CurrentCellIndex, CellType::Nothing);

			m_ballBigPosition.erase(m_ballBigPosition.begin() + x);

			m_powerupKillCounter = 0;
			m_ghostKillTimer.start();
			ghostForceRefresh = true;

			m_sound.setBuffer(m_powerupSound);
			m_sound.play();

			for(unsigned int x = 0; x < m_ghostCount; ++x)
			{
				m_ghost[x].Invulnerable = false;
			}

			addScore(50);

			if(m_ballPosition.empty() && m_ballBigPosition.empty())
			{
				resetGame();

				return;
			}
		}
	}

	if(m_ghostKillTimer.getTicks() > 7000)
	{
		m_ghostKillTimer.stop();

		for(unsigned int x = 0; x < m_ghostCount; ++x)
		{
			m_ghost[x].Invulnerable = false;

			m_ghost[x].LastStateChange = m_gameTimer.getTicks();
			m_ghost[x].StateDuration = 3000;
			m_ghost[x].IsInChase = true;
		}

		ghostForceRefresh = true;
	}

	// IA Fantasmas
	for(unsigned int x = 0; x < m_ghostCount; ++x)
	{
		if(m_ghost[x].TimeToRelease >= m_gameTimer.getTicks())
		{
			break;
		}

		unsigned int ignoreCell;

		if(m_ghost[x].Direction == ViewDirection::Left)
		{
			ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Right);
		}
		else if(m_ghost[x].Direction == ViewDirection::Right)
		{
			ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Left);
		}
		else if(m_ghost[x].Direction == ViewDirection::Up)
		{
			ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Down);
		}
		else
		{
			ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Up);
		}

		float ghostMoveSpeed = m_ghostKillTimer.isStarted() && (m_ghost[x].IsDead ? false : !m_ghost[x].Invulnerable) ?
			(m_ghost[x].MoveSpeed / 2) :
			(m_ghost[x].IsDead ? m_ghost[x].MoveSpeed * 1.5: m_ghost[x].MoveSpeed);

		if(m_ghost[x].CurrentCellIndex == m_ghost[x].HomeIndex)
		{
			m_ghost[x].IsDead = false;

			if(m_ghostKillTimer.isStarted())
			{
				m_ghost[x].Invulnerable = true;
			}

			m_ghost[x].LastStateChange = m_gameTimer.getTicks();
			m_ghost[x].StateDuration = 1000;
			m_ghost[x].IsInChase = true;
		}

		if(m_gameTimer.getTicks() >= (m_ghost[x].LastStateChange + m_ghost[x].StateDuration))
		{
			if(!m_ghostKillTimer.isStarted())
			{
				ghostForceRefresh = true;
			}

			m_ghost[x].LastStateChange = m_gameTimer.getTicks();

			if(m_ghost[x].IsInChase)
			{
				m_ghost[x].IsInChase = false;
				m_ghost[x].StateDuration = (3000 + (rand() % 3000));
			}
			else
			{
				m_ghost[x].IsInChase = true;
				m_ghost[x].StateDuration = (5000 + (rand() % 3000));
			}
		}

		if(m_ghost[x].LastCellChecked != m_ghost[x].CurrentCellIndex || ghostForceRefresh)
		{
			if(m_ghost[x].IsDead)
			{
				m_ghost[x].DesiredDirection = getNextDirection(m_ghost[x].CurrentCellIndex, m_ghost[x].HomeIndex, ignoreCell);

			}
			else if(m_ghost[x].IsInChase && (!m_ghostKillTimer.isStarted() || m_ghost[x].Invulnerable))
			{
				if(m_ghost[x].CurrentCellIndex != m_player.CurrentCellIndex)
				{
					m_ghost[x].DesiredDirection = getNextDirection(m_ghost[x].CurrentCellIndex, m_player.CurrentCellIndex, ignoreCell);
				}
			}
			else
			{
				unsigned int tempIndex;
				std::vector<unsigned int> possibleCells;

				if(m_ghost[x].Direction != ViewDirection::Left)
				{
					tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Left);

					if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall)
					{
						possibleCells.push_back(tempIndex);
					}
				}

				if(m_ghost[x].Direction != ViewDirection::Right)
				{
					tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Right);

					if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall)
					{
						possibleCells.push_back(tempIndex);
					}
				}

				if(m_ghost[x].Direction != ViewDirection::Up)
				{
					tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Up);

					if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall)
					{
						possibleCells.push_back(tempIndex);
					}
				}

				if(m_ghost[x].Direction != ViewDirection::Down)
				{
					tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Down);

					if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall)
					{
						possibleCells.push_back(tempIndex);
					}
				}

				// Si hay caminos alternativos a seguir (Que no sea ni a donde se dirige ni la casilla anterior) o es un callejón sin salida...
				if(possibleCells.size() > 0 || getMapInfo(m_ghost[x].CurrentCellIndex, m_ghost[x].Direction) == CellType::Wall)
				{
					m_ghost[x].DesiredDirection = getRandomDirection(m_ghost[x].CurrentCellIndex, ignoreCell);
				}
			}

			m_ghost[x].LastCellChecked = m_ghost[x].CurrentCellIndex;
		}

		moveEntity(&m_ghost[x].CurrentCellIndex, &m_ghost[x].PositionOffset, &m_ghost[x].Direction, &m_ghost[x].DesiredDirection, &m_ghost[x].Moving, ghostMoveSpeed, false);

		if(!m_ghost[x].IsDead)
		{
			// Calcular colisión con Pacman
			if(m_ghost[x].CurrentCellIndex == m_player.CurrentCellIndex)
			{
				ghostCollide(x);
			}
			else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Left) == m_player.CurrentCellIndex)
			{
				if((m_player.PositionOffset.x + (m_tileSize.x / 2)) - (m_ghost[x].PositionOffset.x + (m_tileSize.x / 2)) >= 0)
				{
					ghostCollide(x);
				}
			}
			else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Right) == m_player.CurrentCellIndex)
			{
				if((m_ghost[x].PositionOffset.x + (m_tileSize.x / 2)) - (m_player.PositionOffset.x + (m_tileSize.x / 2)) >= 0)
				{
					ghostCollide(x);
				}
			}
			else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Up) == m_player.CurrentCellIndex)
			{
				if((m_player.PositionOffset.y + (m_tileSize.y / 2)) - (m_ghost[x].PositionOffset.y + (m_tileSize.y / 2)) >= 0)
				{
					ghostCollide(x);
				}
			}
			else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Down) == m_player.CurrentCellIndex)
			{
				if((m_ghost[x].PositionOffset.y + (m_tileSize.y / 2)) - (m_player.PositionOffset.y + (m_tileSize.y / 2)) >= 0)
				{
					ghostCollide(x);
				}
			}
		}
	}
}
Pacman::ViewDirection Pacman::getNextDirection(unsigned int startIndex, unsigned int searchIndex, unsigned int ignoreCell)
{
	std::list<Node> OpenNodeList;
	std::list<Node> ClosedNodeList;

	// Guardamos en la lista de Nodos Abiertos el Nodo correspondiente a startIndex
	OpenNodeList.push_back(Node());
	OpenNodeList.back().Index = startIndex;
	OpenNodeList.back().Range = abs((startIndex % m_mapSize.x) - (searchIndex % m_mapSize.x)) + abs(floor(startIndex / m_mapSize.y) - floor(searchIndex / m_mapSize.y));

	if(ignoreCell == m_mapNullCell)
	{
		// Guardamos en la lista de Nodos Cerrados el Nodo correspondiente a la casilla a ignorar
		ClosedNodeList.push_back(Node());
		ClosedNodeList.back().Index = ignoreCell;
	}

	Node* preferentNode = &OpenNodeList.back();

	// Hasta que no encuentre el destino o la lista de nodos abiertos se vacíe (no haya caminos posibles)...
	while (preferentNode->Index != searchIndex && !OpenNodeList.empty())
	{
		// Si el nodo preferente está en la lista de nodos cerrados...
		for (auto closedNode : ClosedNodeList)
		{
			if (closedNode.Index == preferentNode->Index)
			{
				preferentNode = &OpenNodeList.back();

				// Elegimos el primer nodo más preferente de la lista de nodos abiertos
				for (auto openNodeIt = OpenNodeList.begin(); openNodeIt != OpenNodeList.end(); ++openNodeIt)
				//for (auto openNode : OpenNodeList)
				{
					if ((preferentNode->Range + preferentNode->Cost) > (openNodeIt->Range + openNodeIt->Cost))
					{
						preferentNode = &*openNodeIt;
					}
				}

				break;
			}
		}

		// Guardamos el nodo preferente en la lista de Nodos cerrados y lo eliminamos de la lista de nodos abiertos
		for (auto openNodeIt = OpenNodeList.begin(); openNodeIt != OpenNodeList.end(); ++openNodeIt)
		{
			if (openNodeIt->Index == preferentNode->Index)
			{
				ClosedNodeList.push_back(*preferentNode);

				// Actualizamos los punteros
				for (Node openNode : OpenNodeList)
				{
					if(openNode.ParentNode == preferentNode)
					{
						openNode.ParentNode = &ClosedNodeList.back();
					}
				}

				preferentNode = &ClosedNodeList.back();

				OpenNodeList.erase(openNodeIt);

				break;
			}
		}

		std::vector<unsigned int> nextIndex;

		// Añadimos a nextIndex CADA UNA de las 4 direcciones si es posible su tránsito
		if (!checkCollision(preferentNode->Index, ViewDirection::Left, false))
		{
			nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Left));
		}
		if (!checkCollision(preferentNode->Index, ViewDirection::Right, false))
		{
			nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Right));
		}
		if (!checkCollision(preferentNode->Index, ViewDirection::Up, false))
		{
			nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Up));
		}
		if (!checkCollision(preferentNode->Index, ViewDirection::Down, false))
		{
			nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Down));
		}

		if (!nextIndex.empty())
		{
			Node* previousNode = preferentNode;

			for (unsigned int Index : nextIndex)
			{
				bool isValid = true;

				// Miramos si existe en la lista de nodos abiertos
				for (Node openNode : OpenNodeList)
				{
					if (openNode.Index == Index)
					{
						isValid = false;

						break;
					}
				}

				if (!isValid)
				{
					continue;
				}

				// Miramos si existe en la lista de nodos cerrados
				for (Node closedNode : ClosedNodeList)
				{
					if (closedNode.Index == Index)
					{
						isValid = false;

						break;
					}
				}

				if (!isValid)
				{
					continue;
				}

				// Si NO existe en ninguna de las listas anteriores, añadimos el nodo a la lista de nodos abiertos
				OpenNodeList.push_back(Node());
				OpenNodeList.back().Index = Index;
				OpenNodeList.back().ParentNode = previousNode;
				OpenNodeList.back().Cost = (previousNode->Cost + 1);
				OpenNodeList.back().Range = abs((int)(Index % m_mapSize.x) - (int)(searchIndex % m_mapSize.x)) + abs(floor(Index / m_mapSize.y) - floor(searchIndex / m_mapSize.y));

				// ... y actualizamos preferentNode si así fuera el caso
				if ((preferentNode->Range + preferentNode->Cost) > (OpenNodeList.back().Range + OpenNodeList.back().Cost))
				{
					preferentNode = &OpenNodeList.back();
				}
			}
		}
	}

	// Si el ultimo nodo preferente encontró el destino...
	if (preferentNode->Index == searchIndex)
	{
		// Localizamos el nodo con la siguiente casilla a desplazarse desde el nodo destino
		while (preferentNode->ParentNode->Index != startIndex)
		{
			preferentNode = preferentNode->ParentNode;
		}

		// Nos movemos en una dirección segun el nodo posterior al nodo origen
		if (preferentNode->Index == (startIndex - 1))
		{
			return ViewDirection::Left;
		}
		else if (preferentNode->Index == (startIndex + 1))
		{
			return ViewDirection::Right;
		}
		else if (preferentNode->Index == (startIndex + m_mapSize.x))
		{
			return ViewDirection::Down;
		}
		else
		{
			return ViewDirection::Up;
		}
	}
	else
	{
		return getRandomDirection(startIndex, ignoreCell);
	}
}
void *allocBlock(terryManageHead *head , int size)
{
    assert(head != NULL && size > 0);
    if(size < 0 || size > MAX_SIZE)
    {
        printf("WARNING : can not allocate block of size %d\n" , size);
        return NULL;
    }
    int realSize = size + BLOCK_INFO_SIZE;

//  printf("alloc a block of size %d and real alloc size is %d\n" , size , realSize);

    int cacheIndex = head->cache;
    terryMemPool *memPool = NULL;
    //if we can use cache do not need to calculate which manage we should use...
    if(cacheIndex != -1)
    {
        struct mapInfo *mapPtr = head->map;
        if(0 == cacheIndex && realSize >= FRONT_ALIGN_SIZE(mapPtr[cacheIndex].size) && realSize <= mapPtr[cacheIndex].size)
            memPool = mapPtr[cacheIndex].addr;
        else if(realSize >= FRONT_ALIGN_SIZE(mapPtr[cacheIndex].size) && realSize <= mapPtr[cacheIndex].size)
            memPool = mapPtr[cacheIndex].addr;

    }

    if(NULL == memPool)
    {
        int mapIndex = getMapIndex(head , realSize);

        if(-1 == mapIndex)
        {
            memPool = createManageStrcut(head , DO_ALIGN_SIZE(realSize));
            if(NULL == memPool)
                return NULL;
        }
        else
        {
            memPool = (terryMemPool *)((head->map)[mapIndex].addr);
            head->cache = mapIndex;
        }
    }

    //if there is no free block , expand this memory pool then allocate block....
    if(0 == memPool->allFreeNumber)
        expandMemPool(memPool);

    terryBlockManage *blockManage = memPool->cache;
    if(blockManage == NULL || 0 == blockManage->freeNumber)
    {
        blockManage = memPool->allocList;
        while(blockManage->freeNumber == 0)
            blockManage = blockManage->next;
    }
    //delete this block from free list...
    terryBlockInfo *blockInfoPtr = blockManage->free;
    blockManage->free = (blockInfoPtr->ptr).next;
    blockManage->freeNumber --;
    blockManage->inuseNumber ++;

    /*  
    //add this block to using list... 
    if(NULL == memPool->inuse)
    {
        memPool->inuse = blockInfoPtr;
        blockInfoPtr->next = blockInfoPtr->prev = NULL;
    }
    else
    {
        memPool->inuse->prev = blockInfoPtr;
        blockInfoPtr->next = memPool->inuse;
        memPool->inuse = blockInfoPtr;
    }
    */

    memPool->allFreeNumber --;
    memPool->allInuseNumber ++;

    (blockInfoPtr->ptr).magic = head->magic;
    blockInfoPtr->manage = blockManage;
    return (void *)((char *)blockInfoPtr + BLOCK_INFO_SIZE);
}