libgdx / gdx-ai

Artificial Intelligence framework for games based on libGDX or not. Features: Steering Behaviors, Formation Motion, Pathfinding, Behavior Trees and Finite State Machines

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

index 81 out of bounds for length 81

MorphicDreamer opened this issue · comments

Please ensure you have given all the following requested information in your report.

Issue details

Please provide the details of your issue
Gdx.ai is giving a cryptic error saying that "index 81 is out of bounds for length 81"
the map that I am using Gdx.ai is a 9X9 isometric map not including index 0 e.g. tiles[8][8] is the top of the map

Reproduction steps/code

Please provide the steps to reproduce this issue, or even better, a SSCCE that reproduces your issue.
I used someones implementation of code to find neighboring tiles connecttiles(tiles(tiles[x][y]), tiles[x][y-1]) and the code works for most examples but it fails on any tiles you move from tiles[7][7]

Version of gdx-ai and/or relevant dependencies

i am using libgdx version 1.100
and Gdx.ai 1.8.2

Stacktrace

Exception in thread "LWJGL Application" java.lang.ArrayIndexOutOfBoundsException: Index 81 out of bounds for length 81
at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.getNodeRecord(IndexedAStarPathFinder.java:279)
at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.visitChildren(IndexedAStarPathFinder.java:204)
at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:117)
at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:94)
at com.mygdx.game.map.map.findpath(map.kt:118)
at com.mygdx.game.map.map.tileinfo(map.kt:101)
at com.mygdx.game.Player.Units.baseunit.mouse(baseunit.kt:75)
at com.mygdx.game.Player.Units.baseunit.render(baseunit.kt:38)
at com.mygdx.game.Screens.gameScreen.render(gameScreen.kt:53)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.mygdx.game.MyGdxGame.render(MyGdxGame.kt:29)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:232)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:127)



####code for map (if necessary)
package com.mygdx.game.map

import com.badlogic.gdx.Gdx
import com.badlogic.gdx.ai.pfa.Connection
import com.badlogic.gdx.ai.pfa.DefaultGraphPath
import com.badlogic.gdx.ai.pfa.GraphPath
import com.badlogic.gdx.ai.pfa.Heuristic
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder
import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.math.Vector3
import com.badlogic.gdx.utils.Array
import com.badlogic.gdx.utils.ObjectMap
import com.mygdx.game.Player.PlayerCamera
import kotlin.math.floor
import kotlin.properties.Delegates

class map(tilesimg: Texture) : IndexedGraph<Tile>{

    var tiles: ArrayList<ArrayList<Tile>> = arrayListOf(arrayListOf())
    private var tileheuristic: TileHeuristic = TileHeuristic()
    private var connections: ArrayList<Aconnection> = arrayListOf()
    private var connectionsmap: ObjectMap<Tile, Array<Connection<Tile>>> = ObjectMap()
    private var Tiles: Texture = tilesimg
    private var grassimg: TextureRegion = TextureRegion(Tiles, 128, 64, 128, 64)
    lateinit var tilepath: GraphPath<Tile>

    var index: Int = 0

    init {
        for(x in 0..8){
            tiles.add(arrayListOf())
            for(y in 0..8){
                index++
                tiles[x].add(Tile(Vector2((y-x)*64f, (y+x)*32f), grassimg, arrayListOf(x, y), index))
            }
        }
        for(tilex in 0..tiles.size)
            for(tile in 0..8){

                if(tilex + 1 <= 8 && tile + 1 <= 8) {

                    if (tilex+1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex + 1][tile + 0])
                    if (tile+1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex + 0][tile + 1])
                    if (tilex-1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex - 1][tile - 0])
                    if (tile-1 >= 0) {
                        connecttiles(tiles[tilex][tile], tiles[tilex - 0][tile - 1])
                        println(Vector2(tilex.toFloat(), tile.toFloat()))
                        println(Vector2(tilex.toFloat() + 1, tile.toFloat() + 1))
                    }
                    if (tilex+1 >= 0 && tile+1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex + 1][tile + 1])
                    if (tilex-1 >= 0 && tile-1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex - 1][tile - 1])

                }

            }

/*

        for(tilex in 0..5)
            for(tile in 0..5){

                if(tilex - 1 < 5 && tile - 1 < 5) {
                    println(Vector2(tilex.toFloat(), tile.toFloat()))
                    println(Vector2(tilex.toFloat()-1, tile.toFloat()-1))
                    println("")
                    if(tilex-1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex - 1][tile - 0])
                    if (tile-1 >= 0)
                        connecttiles(tiles[tilex][tile], tiles[tilex - 0][tile - 1])


                }
            }

 */

    }


    fun render(batch: SpriteBatch){
        for(tilex in tiles)
            for(tile in tilex)
                tile.render(batch)


    }

    fun tileinfo(position: Vector2, wantposition: Vector2): GraphPath<Tile>{
        println(position)
        println(wantposition)

        tilepath = findpath(tiles[position.x.toInt()][position.y.toInt()], tiles[wantposition.x.toInt()][wantposition.y.toInt()])
        //tilepath = findpath(tiles[0][0], tiles[1][1])
        //for (path in tilepath)
            //println(path.position)
        return tilepath
    }
    fun connecttiles(fromtile: Tile, totile: Tile){
        val street = Aconnection(fromtile, totile)
        if(!connectionsmap.containsKey(fromtile)){
            connectionsmap.put(fromtile, Array<Connection<Tile>>())
        }
        connectionsmap.get(fromtile).add(street)
        connections.add(street)
    }

    fun findpath(startTile: Tile, endTile: Tile) : GraphPath<Tile>{
        val tilepath: GraphPath<Tile> = DefaultGraphPath()
        IndexedAStarPathFinder(this).searchNodePath(startTile, endTile, tileheuristic, tilepath)
        return tilepath

    }

    override fun getConnections(fromNode: Tile?): Array<Connection<Tile>> {
        if(connectionsmap.containsKey(fromNode)){
            return connectionsmap.get(fromNode)
        }
        return Array(0)
    }

    override fun getIndex(node: Tile?): Int {
        return node!!.index
    }

    override fun getNodeCount(): Int {
        return index
    }



}

commented

It looks like a bug in your code : index is incremented before adding a new tile, so your indexing is not zero based. Moving index++ after adding the tile may fix your issue. Node indexing should always be zero based (starting at zero).

Thanks so much @mgsx-dev. It worked! :)