libgdx/gdx-ai

Pathfinding uses identity to determine when destination reached

nanodeath opened this issue · 0 comments

Issue details

IndexedAStarPathFinder assumes that you have a known-ahead-of-time finite graph prepopulated with nodes that you can pass in as arguments to searchNodePath.

In my code, as the algorithm is "exploring", it generates new connections and nodes on the fly, which seems reasonable, as I'm modeling my grid using Vector2s. However, because of this line of code, the code never terminates, because current.node will never have the same identity as endNode.

What I'd like to see is either current.node == endNode replaced with Object.equals(current.node, endNode), or a call to a protected method that I can override, e.g. isAtDestination(current.node, endNode) or nodesEqual(curent.node, endNode).

Reproduction steps/code

Please provide the steps to reproduce this issue, or even better, a SSCCE that reproduces your issue.

Here are the relevant bits of my code:

    // <snip>
    private fun Entity.moveTowards(players: ImmutableArray<Entity>): Vector2? {
        val player = players.first()
        val myPos = positionFor[this]
        val graph = MyGraph(currentLevel)
        val out = DefaultGraphPath<Vector2>()
        println("Getting path from $myPos to ${positionFor[player]}")
        if (IndexedAStarPathFinder(graph).searchNodePath(myPos.toVector2(), positionFor[player].toVector2(), { node, endNode -> node.dst(endNode) }, out)) {
            return out.get(0)
        }
        return null
    }
}

class MyGraph(private val currentLevel: Level) : IndexedGraph<Vector2> {
    override fun getConnections(fromNode: Vector2): Array<Connection<Vector2>> = listOf(
            Vector2(fromNode.x - 1, fromNode.y),
            Vector2(fromNode.x + 1, fromNode.y),
            Vector2(fromNode.x, fromNode.y - 1),
            Vector2(fromNode.x, fromNode.y + 1)
    )
            .filter { currentLevel.isWalkable(it.x, it.y) }
            .map { MyConnection(from = fromNode, to = it) }
            .let { Array(it.toTypedArray()) }

    override fun getIndex(node: Vector2): Int = (node.x + node.y * currentLevel.width).toInt()

    override fun getNodeCount(): Int = currentLevel.width * currentLevel.height
}

class MyConnection(private val from: Vector2, private val to: Vector2) : Connection<Vector2> {
    override fun getFromNode() = from
    override fun getToNode() = to
    override fun getCost() = 1F
}

Version of gdx-ai and/or relevant dependencies

gdx-ai 1.8.1

Stacktrace

No stacktrace.