예제 #1
0
/**
 * Performs the actual search.
 */
IPath::SearchResult CPathEstimator::DoSearch(const MoveData& moveData, const CPathFinderDef& peDef) {
	bool foundGoal = false;

	while (!openBlocks.empty() && (openBlockBufferIndex < maxBlocksToBeSearched)) {
		// get the open block with lowest cost
		OpenBlock* ob = openBlocks.top();
		openBlocks.pop();

		// check if the block has been marked as unaccessible during its time in the queue
		if (blockState[ob->blocknr].options & (PATHOPT_BLOCKED | PATHOPT_CLOSED | PATHOPT_FORBIDDEN))
			continue;

		// no, check if the goal is already reached
		int xBSquare = blockState[ob->blocknr].sqrCenter[moveData.pathType].x;
		int zBSquare = blockState[ob->blocknr].sqrCenter[moveData.pathType].y;
		int xGSquare = ob->block.x * BLOCK_SIZE + goalSqrOffset.x;
		int zGSquare = ob->block.y * BLOCK_SIZE + goalSqrOffset.y;

		if (peDef.IsGoal(xBSquare, zBSquare) || peDef.IsGoal(xGSquare, zGSquare)) {
			goalBlock = ob->block;
			goalHeuristic = 0;
			foundGoal = true;
			break;
		}

		// no, test the 8 surrounding blocks
		// NOTE: each of these calls increments openBlockBufferIndex by 1, so
		// maxBlocksToBeSearched is always less than <MAX_SEARCHED_BLOCKS - 8>
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT);
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT_UP);
		TestBlock(moveData, peDef, *ob, PATHDIR_UP);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT_UP);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT_DOWN);
		TestBlock(moveData, peDef, *ob, PATHDIR_DOWN);
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT_DOWN);

		// mark this block as closed
		blockState[ob->blocknr].options |= PATHOPT_CLOSED;
	}

	// we found our goal
	if (foundGoal)
		return Ok;

	// we could not reach the goal
	if (openBlockBufferIndex >= maxBlocksToBeSearched)
		return GoalOutOfRange;

	// search could not reach the goal due to the unit being locked in
	if (openBlocks.empty())
		return GoalOutOfRange;

	// should never happen
	LogObject() << "ERROR: CPathEstimator::DoSearch() - Unhandled end of search!\n";
	return Error;
}
예제 #2
0
/**
 * Performs the actual search.
 */
IPath::SearchResult CPathEstimator::DoSearch(const MoveData& moveData, const CPathFinderDef& peDef, bool synced) {
	bool foundGoal = false;

	while (!openBlocks.empty() && (openBlockBuffer.GetSize() < maxBlocksToBeSearched)) {
		// get the open block with lowest cost
		PathNode* ob = const_cast<PathNode*>(openBlocks.top());
		openBlocks.pop();

		// check if the block has been marked as unaccessible during its time in the queue
		if (blockStates[ob->nodeNum].nodeMask & (PATHOPT_BLOCKED | PATHOPT_CLOSED | PATHOPT_FORBIDDEN))
			continue;

		// no, check if the goal is already reached
		const int xBSquare = blockStates[ob->nodeNum].nodeOffsets[moveData.pathType].x;
		const int zBSquare = blockStates[ob->nodeNum].nodeOffsets[moveData.pathType].y;
		const int xGSquare = ob->nodePos.x * BLOCK_SIZE + goalSqrOffset.x;
		const int zGSquare = ob->nodePos.y * BLOCK_SIZE + goalSqrOffset.y;

		if (peDef.IsGoal(xBSquare, zBSquare) || peDef.IsGoal(xGSquare, zGSquare)) {
			goalBlock = ob->nodePos;
			goalHeuristic = 0;
			foundGoal = true;
			break;
		}

		// no, test the 8 surrounding blocks
		// NOTE: each of these calls increments openBlockBuffer.idx by 1, so
		// maxBlocksToBeSearched is always less than <MAX_SEARCHED_NODES_PE - 8>
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT,       synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT_UP,    synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_UP,         synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT_UP,   synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT,      synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT_DOWN, synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_DOWN,       synced);
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT_DOWN,  synced);

		// mark this block as closed
		blockStates[ob->nodeNum].nodeMask |= PATHOPT_CLOSED;
	}

	// we found our goal
	if (foundGoal)
		return IPath::Ok;

	// we could not reach the goal
	if (openBlockBuffer.GetSize() >= maxBlocksToBeSearched)
		return IPath::GoalOutOfRange;

	// search could not reach the goal due to the unit being locked in
	if (openBlocks.empty())
		return IPath::GoalOutOfRange;

	// should never happen
	LogObject() << "ERROR: CPathEstimator::DoSearch() - Unhandled end of search!\n";
	return IPath::Error;
}
/*
Performs the actual search.
*/
IPath::SearchResult CPathEstimator::DoSearch(const MoveData& moveData, const CPathFinderDef& peDef) {
	bool foundGoal = false;
	while(!openBlocks.empty() && (openBlockBufferPointer - openBlockBuffer) < (maxBlocksToBeSearched - 8)) {
		//Get the open block with lowest cost.
		OpenBlock* ob = openBlocks.top();
		openBlocks.pop();

		//Check if the block has been marked as unaccessable during it's time in queue.
		if(blockState[ob->blocknr].options & (PATHOPT_BLOCKED | PATHOPT_CLOSED | PATHOPT_FORBIDDEN))
			continue;

		//Check if the goal is reached.
		int xBSquare = blockState[ob->blocknr].sqrCenter[moveData.pathType].x;
		int zBSquare = blockState[ob->blocknr].sqrCenter[moveData.pathType].y;
		int xGSquare = ob->block.x * BLOCK_SIZE + goalSqrOffset.x;
		int zGSquare = ob->block.y * BLOCK_SIZE + goalSqrOffset.y;
		if(peDef.IsGoal(xBSquare, zBSquare) || peDef.IsGoal(xGSquare, zGSquare)) {
			goalBlock = ob->block;
			goalHeuristic = 0;
			foundGoal = true;
			break;
		}

		//Test the 8 surrounding blocks.
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT);
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT_UP);
		TestBlock(moveData, peDef, *ob, PATHDIR_UP);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT_UP);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT);
		TestBlock(moveData, peDef, *ob, PATHDIR_RIGHT_DOWN);
		TestBlock(moveData, peDef, *ob, PATHDIR_DOWN);
		TestBlock(moveData, peDef, *ob, PATHDIR_LEFT_DOWN);

		//Mark this block as closed.
		blockState[ob->blocknr].options |= PATHOPT_CLOSED;
	}

	//Returning search-result.
	if(foundGoal)
		return Ok;

	//Could not reach the goal.
	if(openBlockBufferPointer - openBlockBuffer >= (maxBlocksToBeSearched - 8))
		return GoalOutOfRange;

	//Search could not reach the goal, due to the unit being locked in.
	if(openBlocks.empty())
		return GoalOutOfRange;

	//Below shall never be runned.
	logOutput << "ERROR: CPathEstimator::DoSearch() - Unhandled end of search!\n";
	return Error;
}
예제 #4
0
/*
Performs the actual search.
*/
IPath::SearchResult CPathFinder::DoSearch(const MoveData& moveData, const CPathFinderDef& pfDef) {
    bool foundGoal = false;
    while(!openSquares.empty() && openSquareBufferPointer - openSquareBuffer < (maxNodesToBeSearched - 8)) {
        //Gets the open square with lowest expected path-cost.
        OpenSquare* os = openSquares.top();
        openSquares.pop();

        //Check if this OpenSquare-holder have become obsolete.
        if(squareState[os->sqr].cost != os->cost)
            continue;

        //Check if the goal is reached.
        if(pfDef.IsGoal(os->square.x, os->square.y)) {
            goalSquare = os->sqr;
            goalHeuristic = 0;
            foundGoal = true;
            break;
        }

        //Testing the 8 surrounding squares.
        bool right=TestSquare(moveData, pfDef, os, PATHOPT_RIGHT);
        bool left=TestSquare(moveData, pfDef, os, PATHOPT_LEFT);
        bool up=TestSquare(moveData, pfDef, os, PATHOPT_UP);
        bool down=TestSquare(moveData, pfDef, os, PATHOPT_DOWN);
        if(up) {		//we dont want to search diagonally if there is a blocking object (not blocking terrain) in one of the two side squares
            if(right)
                TestSquare(moveData, pfDef, os, (PATHOPT_RIGHT | PATHOPT_UP));
            if(left)
                TestSquare(moveData, pfDef, os, (PATHOPT_LEFT | PATHOPT_UP));
        }
        if(down) {
            if(right)
                TestSquare(moveData, pfDef, os, (PATHOPT_RIGHT | PATHOPT_DOWN));
            if(left)
                TestSquare(moveData, pfDef, os, (PATHOPT_LEFT | PATHOPT_DOWN));
        }

        //Mark this square as closed.
        squareState[os->sqr].status |= PATHOPT_CLOSED;
    }

    //Returning search-result.
    if(foundGoal)
        return Ok;

    //Could not reach the goal.
    if(openSquareBufferPointer - openSquareBuffer >= (maxNodesToBeSearched - 8))
        return GoalOutOfRange;

    //Search could not reach the goal, due to the unit being locked in.
    if(openSquares.empty())
        return GoalOutOfRange;

    //Below shall never be runned.
    *info << "ERROR: CPathFinder::DoSearch() - Unhandled end of search!\n";
    return Error;
}
예제 #5
0
IPath::SearchResult CPathFinder::InitSearch(const MoveDef& moveDef, const CPathFinderDef& pfDef, const CSolidObject* owner, bool synced) {
    // If exact path is reqired and the goal is blocked, then no search is needed.
    if (exactPath && pfDef.GoalIsBlocked(moveDef, CMoveMath::BLOCK_STRUCTURE, owner))
        return IPath::CantGetCloser;

    // Clamp the start position
    if (startxSqr >= gs->mapx) {
        startxSqr = gs->mapxm1;
    }
    if (startzSqr >= gs->mapy) {
        startzSqr = gs->mapym1;
    }

    const bool isStartGoal = pfDef.IsGoal(startxSqr, startzSqr);
    // although our starting square may be inside the goal radius, the starting coordinate may be outside.
    // in this case we do not want to return CantGetCloser, but instead a path to our starting square.
    if (isStartGoal && pfDef.startInGoalRadius)
        return IPath::CantGetCloser;

    // Clear the system from last search.
    ResetSearch();

    // Marks and store the start-square.
    squareStates.nodeMask[mStartSquareIdx] = (PATHOPT_START | PATHOPT_OPEN);
    squareStates.fCost[mStartSquareIdx] = 0.0f;
    squareStates.gCost[mStartSquareIdx] = 0.0f;

    squareStates.SetMaxCost(NODE_COST_F, 0.0f);
    squareStates.SetMaxCost(NODE_COST_G, 0.0f);

    dirtySquares.push_back(mStartSquareIdx);

    // Make the beginning the fest square found.
    mGoalSquareIdx = mStartSquareIdx;
    mGoalHeuristic = pfDef.Heuristic(startxSqr, startzSqr);

    // Adding the start-square to the queue.
    openSquareBuffer.SetSize(0);
    PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize());
    os->fCost     = 0.0f;
    os->gCost     = 0.0f;
    os->nodePos.x = startxSqr;
    os->nodePos.y = startzSqr;
    os->nodeNum   = mStartSquareIdx;
    openSquares.push(os);

    // perform the search
    IPath::SearchResult result = DoSearch(moveDef, pfDef, owner, synced);

    // if no improvements are found, then return CantGetCloser instead
    if ((mGoalSquareIdx == mStartSquareIdx && (!isStartGoal || pfDef.startInGoalRadius)) || mGoalSquareIdx == 0) {
        return IPath::CantGetCloser;
    }

    return result;
}
예제 #6
0
/**
 * Performs the actual search.
 */
IPath::SearchResult CPathFinder::DoSearch(const MoveData& moveData, const CPathFinderDef& pfDef, int ownerId, bool synced) {
	bool foundGoal = false;

	while (!openSquares.empty() && (openSquareBuffer.GetSize() < maxSquaresToBeSearched)) {
		// Get the open square with lowest expected path-cost.
		PathNode* os = const_cast<PathNode*>(openSquares.top());
		openSquares.pop();

		// check if this PathNode has become obsolete
		if (squareStates[os->nodeNum].fCost != os->fCost)
			continue;

		// Check if the goal is reached.
		if (pfDef.IsGoal(os->nodePos.x, os->nodePos.y)) {
			goalSquare = os->nodeNum;
			goalHeuristic = 0;
			foundGoal = true;
			break;
		}

		// Test the 8 surrounding squares.
		const bool right = TestSquare(moveData, pfDef, os, PATHOPT_RIGHT, ownerId, synced);
		const bool left  = TestSquare(moveData, pfDef, os, PATHOPT_LEFT,  ownerId, synced);
		const bool up    = TestSquare(moveData, pfDef, os, PATHOPT_UP,    ownerId, synced);
		const bool down  = TestSquare(moveData, pfDef, os, PATHOPT_DOWN,  ownerId, synced);

		if (up) {
			// we dont want to search diagonally if there is a blocking object
			// (not blocking terrain) in one of the two side squares
			if (right) { TestSquare(moveData, pfDef, os, (PATHOPT_RIGHT | PATHOPT_UP), ownerId, synced); }
			if (left) { TestSquare(moveData, pfDef, os, (PATHOPT_LEFT | PATHOPT_UP), ownerId, synced); }
		}
		if (down) {
			if (right) { TestSquare(moveData, pfDef, os, (PATHOPT_RIGHT | PATHOPT_DOWN), ownerId, synced); }
			if (left) { TestSquare(moveData, pfDef, os, (PATHOPT_LEFT | PATHOPT_DOWN), ownerId, synced); }
		}

		// Mark this square as closed.
		squareStates[os->nodeNum].nodeMask |= PATHOPT_CLOSED;
	}

	if (foundGoal)
		return IPath::Ok;

	// Could not reach the goal.
	if (openSquareBuffer.GetSize() >= maxSquaresToBeSearched)
		return IPath::GoalOutOfRange;

	// Search could not reach the goal, due to the unit being locked in.
	if (openSquares.empty())
		return IPath::GoalOutOfRange;

	// Below shall never be runned.
	LogObject() << "ERROR: CPathFinder::DoSearch() - Unhandled end of search!\n";
	return IPath::Error;
}
예제 #7
0
// set up the starting point of the search
IPath::SearchResult IPathFinder::InitSearch(const MoveDef& moveDef, const CPathFinderDef& pfDef, const CSolidObject* owner)
{
	int2 square = mStartBlock;

	if (isEstimator)
		square = blockStates.peNodeOffsets[moveDef.pathType][mStartBlockIdx];

	const bool isStartGoal = pfDef.IsGoal(square.x, square.y);
	const bool startInGoal = pfDef.startInGoalRadius;

	// although our starting square may be inside the goal radius, the starting coordinate may be outside.
	// in this case we do not want to return CantGetCloser, but instead a path to our starting square.
	if (isStartGoal && startInGoal)
		return IPath::CantGetCloser;

	// no, clean the system from last search
	ResetSearch();

	// mark and store the start-block
	blockStates.nodeMask[mStartBlockIdx] &= PATHOPT_OBSOLETE; // clear all except PATHOPT_OBSOLETE
	blockStates.nodeMask[mStartBlockIdx] |= PATHOPT_OPEN;
	blockStates.fCost[mStartBlockIdx] = 0.0f;
	blockStates.gCost[mStartBlockIdx] = 0.0f;
	blockStates.SetMaxCost(NODE_COST_F, 0.0f);
	blockStates.SetMaxCost(NODE_COST_G, 0.0f);

	dirtyBlocks.push_back(mStartBlockIdx);

	// start a new search and
	// add the starting block to the open-blocks-queue
	openBlockBuffer.SetSize(0);
	PathNode* ob = openBlockBuffer.GetNode(openBlockBuffer.GetSize());
		ob->fCost   = 0.0f;
		ob->gCost   = 0.0f;
		ob->nodePos = mStartBlock;
		ob->nodeNum = mStartBlockIdx;
	openBlocks.push(ob);

	// mark starting point as best found position
	mGoalBlockIdx  = mStartBlockIdx;
	mGoalHeuristic = pfDef.Heuristic(square.x, square.y);

	// perform the search
	const IPath::SearchResult result = DoSearch(moveDef, pfDef, owner);

	if (result == IPath::Ok)
		return result;
	if (mGoalBlockIdx != mStartBlockIdx)
		return result;

	// if start and goal are within the same block, but distinct squares
	// or considered a single point for search purposes, then we probably
	// can not get closer
	return (!isStartGoal || startInGoal)? IPath::CantGetCloser: result;
}
예제 #8
0
// set up the starting point of the search
IPath::SearchResult CPathFinder::InitSearch(const MoveData& moveData, const CPathFinderDef& pfDef, int ownerId, bool synced) {
	// If exact path is reqired and the goal is blocked, then no search is needed.
	if (exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN)))
		return IPath::CantGetCloser;

	// Clamp the start position
	if (startxSqr <         0) { startxSqr =            0; }
	if (startxSqr >= gs->mapx) { startxSqr = gs->mapx - 1; }
	if (startzSqr <         0) { startzSqr =            0; }
	if (startzSqr >= gs->mapy) { startzSqr = gs->mapy - 1; }

	// If the starting position is a goal position, then no search need to be performed.
	if (pfDef.IsGoal(startxSqr, startzSqr))
		return IPath::CantGetCloser;

	// Clear the system from last search.
	ResetSearch();

	// Marks and store the start-square.
	squareStates[startSquare].nodeMask = (PATHOPT_START | PATHOPT_OPEN);
	squareStates[startSquare].fCost = 0.0f;
	squareStates[startSquare].gCost = 0.0f;
	squareStates.SetMaxFCost(0.0f);
	squareStates.SetMaxGCost(0.0f);

	dirtySquares.push_back(startSquare);

	// Make the beginning the fest square found.
	goalSquare = startSquare;
	goalHeuristic = pfDef.Heuristic(startxSqr, startzSqr);

	// Adding the start-square to the queue.
	openSquareBuffer.SetSize(0);
	PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize());
		os->fCost     = 0.0f;
		os->gCost     = 0.0f;
		os->nodePos.x = startxSqr;
		os->nodePos.y = startzSqr;
		os->nodeNum   = startSquare;
	openSquares.push(os);

	// perform the search
	IPath::SearchResult result = DoSearch(moveData, pfDef, ownerId, synced);

	// if no improvements are found, then return CantGetCloser instead
	if (goalSquare == startSquare || goalSquare == 0) {
		return IPath::CantGetCloser;
	}

	return result;
}
예제 #9
0
// set up the starting point of the search
IPath::SearchResult CPathEstimator::InitSearch(const MoveData& moveData, const CPathFinderDef& peDef, bool synced) {
	// is starting square inside goal area?
	const int xSquare = blockStates[startBlocknr].nodeOffsets[moveData.pathType].x;
	const int zSquare = blockStates[startBlocknr].nodeOffsets[moveData.pathType].y;

	if (peDef.IsGoal(xSquare, zSquare))
		return IPath::CantGetCloser;

	// no, clean the system from last search
	ResetSearch();

	// mark and store the start-block
	blockStates[startBlocknr].nodeMask |= PATHOPT_OPEN;
	blockStates[startBlocknr].fCost = 0.0f;
	blockStates[startBlocknr].gCost = 0.0f;
	blockStates.SetMaxFCost(0.0f);
	blockStates.SetMaxGCost(0.0f);

	dirtyBlocks.push_back(startBlocknr);

	openBlockBuffer.SetSize(0);
	// add the starting block to the open-blocks-queue
	PathNode* ob = openBlockBuffer.GetNode(openBlockBuffer.GetSize());
		ob->fCost   = 0.0f;
		ob->gCost   = 0.0f;
		ob->nodePos = startBlock;
		ob->nodeNum = startBlocknr;
	openBlocks.push(ob);

	// mark starting point as best found position
	goalBlock = startBlock;
	goalHeuristic = peDef.Heuristic(xSquare, zSquare);

	// get the goal square offset
	goalSqrOffset = peDef.GoalSquareOffset(BLOCK_SIZE);

	// perform the search
	IPath::SearchResult result = DoSearch(moveData, peDef, synced);

	// if no improvements are found, then return CantGetCloser instead
	if (goalBlock.x == startBlock.x && goalBlock.y == startBlock.y) {
		return IPath::CantGetCloser;
	}

	return result;
}
예제 #10
0
/*
Setting up the starting point of the search.
*/
IPath::SearchResult CPathFinder::InitSearch(const MoveData& moveData, const CPathFinderDef& pfDef) {
    //If exact path is reqired and the goal is blocked, then no search is needed.
    if(exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN)))
        return CantGetCloser;

    //Clamp the start position
    if (startxSqr < 0) startxSqr=0;
    if (startxSqr >= gs->mapx) startxSqr = gs->mapx-1;
    if (startzSqr < 0) startzSqr =0;
    if (startzSqr >= gs->mapy) startzSqr = gs->mapy-1;

    //If the starting position is a goal position, then no search need to be performed.
    if(pfDef.IsGoal(startxSqr, startzSqr))
        return CantGetCloser;

    //Clearing the system from last search.
    ResetSearch();

    //Marks and store the start-square.
    squareState[startSquare].status = (PATHOPT_START | PATHOPT_OPEN);
    squareState[startSquare].cost = 0;
    dirtySquares.push_back(startSquare);

    //Make the beginning the fest square found.
    goalSquare = startSquare;
    goalHeuristic = pfDef.Heuristic(startxSqr, startzSqr);

    //Adding the start-square to the queue.
    openSquareBufferPointer = &openSquareBuffer[0];
    OpenSquare *os = openSquareBufferPointer;	//Taking first OpenSquare in buffer.
    os->currentCost = 0;
    os->cost = 0;
    os->square.x = startxSqr;
    os->square.y = startzSqr;
    os->sqr = startSquare;
    openSquares.push(os);

    //Performs the search.
    SearchResult result = DoSearch(moveData, pfDef);

    //If no improvement has been found then return CantGetCloser instead.
    if(goalSquare == startSquare || goalSquare == 0) {
        return CantGetCloser;
    } else
        return result;
}
예제 #11
0
IPath::SearchResult CPathFinder::DoSearch(
	const MoveDef& moveDef,
	const CPathFinderDef& pfDef,
	const CSolidObject* owner
) {
	bool foundGoal = false;

	while (!openBlocks.empty() && (openBlockBuffer.GetSize() < maxBlocksToBeSearched)) {
		// Get the open square with lowest expected path-cost.
		PathNode* openSquare = const_cast<PathNode*>(openBlocks.top());
		openBlocks.pop();

		// check if this PathNode has become obsolete
		if (blockStates.fCost[openSquare->nodeNum] != openSquare->fCost)
			continue;

		// Check if the goal is reached.
		if (pfDef.IsGoal(openSquare->nodePos.x, openSquare->nodePos.y)) {
			mGoalBlockIdx = openSquare->nodeNum;
			mGoalHeuristic = 0.0f;
			foundGoal = true;
			break;
		}

		TestNeighborSquares(moveDef, pfDef, openSquare, owner);
	}

	if (foundGoal)
		return IPath::Ok;

	// could not reach goal within <maxBlocksToBeSearched> exploration limit
	if (openBlockBuffer.GetSize() >= maxBlocksToBeSearched)
		return IPath::GoalOutOfRange;

	// could not reach goal from this starting position if nothing to left to explore
	if (openBlocks.empty())
		return IPath::GoalOutOfRange;

	// should be unreachable
	return IPath::Error;
}
예제 #12
0
/**
 * Make some initial calculations and preparations
 */
IPath::SearchResult CPathEstimator::InitSearch(const MoveData& moveData, const CPathFinderDef& peDef) {
	// is starting square inside goal area?
	int xSquare = blockState[startBlocknr].sqrCenter[moveData.pathType].x;
	int zSquare = blockState[startBlocknr].sqrCenter[moveData.pathType].y;
	if (peDef.IsGoal(xSquare, zSquare))
		return CantGetCloser;

	// no, clean the system from last search
	ResetSearch();

	// mark and store the start-block
	blockState[startBlocknr].options |= PATHOPT_OPEN;
	blockState[startBlocknr].cost = 0;
	dirtyBlocks.push_back(startBlocknr);

	openBlockBufferIndex = 0;
	// add the starting block to the open-blocks-queue
	OpenBlock* ob = &openBlockBuffer[openBlockBufferIndex];
		ob->cost = 0;
		ob->currentCost = 0;
		ob->block = startBlock;
		ob->blocknr = startBlocknr;
	openBlocks.push(ob);

	// mark starting point as best found position
	goalBlock = startBlock;
	goalHeuristic = peDef.Heuristic(xSquare, zSquare);

	// get the goal square offset
	goalSqrOffset = peDef.GoalSquareOffset(BLOCK_SIZE);

	// perform the search
	SearchResult result = DoSearch(moveData, peDef);

	// if no improvements are found, then return CantGetCloser instead
	if (goalBlock.x == startBlock.x && goalBlock.y == startBlock.y)
		return CantGetCloser;
	else
		return result;
}
예제 #13
0
/*
Making some initial calculations and preparations.
*/
IPath::SearchResult CPathEstimator::InitSearch(const MoveData& moveData, const CPathFinderDef& peDef) {
	//Starting square is inside goal area?
	int xSquare = blockState[startBlocknr].sqrCenter[moveData.pathType].x;
	int zSquare = blockState[startBlocknr].sqrCenter[moveData.pathType].y;
	if(peDef.IsGoal(xSquare, zSquare))
		return CantGetCloser;

	//Cleaning the system from last search.
	ResetSearch();

	//Marks and store the start-block.
	blockState[startBlocknr].options |= PATHOPT_OPEN;
	blockState[startBlocknr].cost = 0;
	dirtyBlocks.push_back(startBlocknr);

	//Adding the starting block to the open-blocks-queue.
	OpenBlock* ob = openBlockBufferPointer = openBlockBuffer;
	ob->cost = 0;
	ob->currentCost = 0;
	ob->block = startBlock;
	ob->blocknr = startBlocknr;
	openBlocks.push(ob);

	//Mark starting point as best found position.
	goalBlock = startBlock;
	goalHeuristic = peDef.Heuristic(xSquare, zSquare);

	//Gets goal square offset.
	goalSqrOffset = peDef.GoalSquareOffset(BLOCK_SIZE);

	//Performs the search.
	SearchResult result = DoSearch(moveData, peDef);

	//If no improvements are found, then return CantGetCloser instead.
	if(goalBlock.x == startBlock.x && goalBlock.y == startBlock.y)
		return CantGetCloser;
	else
		return result;
}
예제 #14
0
/**
 * Search with several start positions
 */
IPath::SearchResult CPathFinder::GetPath(
	const MoveData& moveData,
	const std::vector<float3>& startPos,
	const CPathFinderDef& pfDef,
	IPath::Path& path,
	int ownerId,
	bool synced
) {
	// Clear the given path.
	path.path.clear();
	path.squares.clear();
	path.pathCost = PATHCOST_INFINITY;

	// Store som basic data.
	maxSquaresToBeSearched = MAX_SEARCHED_NODES_PF - 8U;
	testMobile = false;
	exactPath = true;
	needPath = true;

	// If exact path is reqired and the goal is blocked, then no search is needed.
	if (exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN)))
		return IPath::CantGetCloser;

	// If the starting position is a goal position, then no search need to be performed.
	if (pfDef.IsGoal(startxSqr, startzSqr))
		return IPath::CantGetCloser;

	// Clearing the system from last search.
	ResetSearch();

	openSquareBuffer.SetSize(0);

	for (std::vector<float3>::const_iterator si = startPos.begin(); si != startPos.end(); ++si) {
		start = *si;
		startxSqr = (int(start.x) / SQUARE_SIZE) | 1;
		startzSqr = (int(start.z) / SQUARE_SIZE) | 1;
		startSquare = startxSqr + startzSqr * gs->mapx;
		goalSquare = startSquare;

		squareStates[startSquare].nodeMask = (PATHOPT_START | PATHOPT_OPEN);
		squareStates[startSquare].fCost = 0.0f;
		squareStates[startSquare].gCost = 0.0f;
		dirtySquares.push_back(startSquare);

		if (openSquareBuffer.GetSize() >= MAX_SEARCHED_NODES_PF) {
			continue;
		}

		PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize());
			os->fCost     = 0.0f;
			os->gCost     = 0.0f;
			os->nodePos.x = startxSqr;
			os->nodePos.y = startzSqr;
			os->nodeNum   = startSquare;
		openSquareBuffer.SetSize(openSquareBuffer.GetSize() + 1);
		openSquares.push(os);
	}

	// note: DoSearch, not InitSearch
	IPath::SearchResult result = DoSearch(moveData, pfDef, ownerId, synced);

	// Respond to the success of the search.
	if (result == IPath::Ok) {
		FinishSearch(moveData, path);
		if (PATHDEBUG) {
			LogObject() << "Path found.\n";
			LogObject() << "Nodes tested: " << testedNodes << "\n";
			LogObject() << "Open squares: " << openSquareBuffer.GetSize() << "\n";
			LogObject() << "Path nodes: " << path.path.size() << "\n";
			LogObject() << "Path cost: " << path.pathCost << "\n";
		}
	} else {
		if (PATHDEBUG) {
			LogObject() << "No path found!\n";
			LogObject() << "Nodes tested: " << testedNodes << "\n";
			LogObject() << "Open squares: " << openSquareBuffer.GetSize() << "\n";
		}
	}
	return result;
}
예제 #15
0
/*
Search with several start positions
*/
IPath::SearchResult CPathFinder::GetPath(const MoveData& moveData, std::vector<float3> startPos, const CPathFinderDef& pfDef, Path& path) {
    //Clear the given path.
    path.path.clear();
    path.pathCost = PATHCOST_INFINITY;

    //Store som basic data.
    maxNodesToBeSearched = MAX_SEARCHED_SQARES;
    testMobile=false;
    exactPath = true;
    needPath=true;

    //If exact path is reqired and the goal is blocked, then no search is needed.
    if(exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN)))
        return CantGetCloser;

    //If the starting position is a goal position, then no search need to be performed.
    if(pfDef.IsGoal(startxSqr, startzSqr))
        return CantGetCloser;

    //Clearing the system from last search.
    ResetSearch();

    openSquareBufferPointer = &openSquareBuffer[0];

    for(std::vector<float3>::iterator si=startPos.begin(); si!=startPos.end(); ++si) {
        start = *si;
        startxSqr = (int(start.x) / SQUARE_SIZE)|1;
        startzSqr = (int(start.z) / SQUARE_SIZE)|1;
        startSquare = startxSqr + startzSqr * gs->mapx;

        squareState[startSquare].status = (PATHOPT_START | PATHOPT_OPEN);
        squareState[startSquare].cost = 0;
        dirtySquares.push_back(startSquare);

        goalSquare = startSquare;

        OpenSquare *os = ++openSquareBufferPointer;	//Taking first OpenSquare in buffer.
        os->currentCost = 0;
        os->cost = 0;
        os->square.x = startxSqr;
        os->square.y = startzSqr;
        os->sqr = startSquare;
        openSquares.push(os);
    }

    //Performs the search.
    SearchResult result = DoSearch(moveData, pfDef);

    //Respond to the success of the search.
    if(result == Ok) {
        FinishSearch(moveData, path);
        if(PATHDEBUG) {
            *info << "Path found.\n";
            *info << "Nodes tested: " << (int)testedNodes << "\n";
            *info << "Open squares: " << (openSquareBufferPointer - openSquareBuffer) << "\n";
            *info << "Path steps: " << (int)(path.path.size()) << "\n";
            *info << "Path cost: " << path.pathCost << "\n";
        }
    } else {
        if(PATHDEBUG) {
            *info << "Path not found!\n";
            *info << "Nodes tested: " << (int)testedNodes << "\n";
            *info << "Open squares: " << (openSquareBufferPointer - openSquareBuffer) << "\n";
        }
    }
    return result;
}
예제 #16
0
// set up the starting point of the search
IPath::SearchResult IPathFinder::InitSearch(const MoveDef& moveDef, const CPathFinderDef& pfDef, const CSolidObject* owner)
{
	int2 square = mStartBlock;

	if (BLOCK_SIZE != 1)
		square = blockStates.peNodeOffsets[moveDef.pathType][mStartBlockIdx];

	const bool isStartGoal = pfDef.IsGoal(square.x, square.y);
	const bool startInGoal = pfDef.startInGoalRadius;

	const bool allowRawPath = pfDef.allowRawPath;
	const bool allowDefPath = pfDef.allowDefPath;

	assert(allowRawPath || allowDefPath);

	// cleanup after the last search
	ResetSearch();

	IPath::SearchResult results[] = {IPath::CantGetCloser, IPath::Ok, IPath::CantGetCloser};

	// although our starting square may be inside the goal radius, the starting coordinate may be outside.
	// in this case we do not want to return CantGetCloser, but instead a path to our starting square.
	if (isStartGoal && startInGoal)
		return results[allowRawPath];

	// mark and store the start-block; clear all bits except PATHOPT_OBSOLETE
	blockStates.nodeMask[mStartBlockIdx] &= PATHOPT_OBSOLETE;
	blockStates.nodeMask[mStartBlockIdx] |= PATHOPT_OPEN;
	blockStates.fCost[mStartBlockIdx] = 0.0f;
	blockStates.gCost[mStartBlockIdx] = 0.0f;
	blockStates.SetMaxCost(NODE_COST_F, 0.0f);
	blockStates.SetMaxCost(NODE_COST_G, 0.0f);

	dirtyBlocks.push_back(mStartBlockIdx);

	// start a new search and add the starting block to the open-blocks-queue
	openBlockBuffer.SetSize(0);
	PathNode* ob = openBlockBuffer.GetNode(openBlockBuffer.GetSize());
		ob->fCost   = 0.0f;
		ob->gCost   = 0.0f;
		ob->nodePos = mStartBlock;
		ob->nodeNum = mStartBlockIdx;
	openBlocks.push(ob);

	// mark starting point as best found position
	mGoalHeuristic = pfDef.Heuristic(square.x, square.y, BLOCK_SIZE);

	enum {
		RAW = 0,
		IPF = 1,
	};

	// perform the search
	results[RAW] = (allowRawPath                                )? DoRawSearch(moveDef, pfDef, owner): IPath::Error;
	results[IPF] = (allowDefPath && results[RAW] == IPath::Error)? DoSearch(moveDef, pfDef, owner): results[RAW];

	if (results[IPF] == IPath::Ok)
		return IPath::Ok;
	if (mGoalBlockIdx != mStartBlockIdx)
		return results[IPF];

	// if start and goal are within the same block but distinct squares (or
	// considered a single point for search purposes), then we probably can
	// not get closer and should return CGC *unless* the caller requested a
	// raw search only
	return results[IPF + ((!allowRawPath || allowDefPath) && (!isStartGoal || startInGoal))];
}