Search code examples
javascriptjqueryhtmla-star

JavaScript - Uncaught TypeError: Cannot set property '0' of undefined


I'm using a A* pathfinding script in a simple JavaScript 2D (canvas) game. I broke my game down to a SSCCE. Anyway, my game is 15 columns across and 10 rows down.

The problem is the error I get. Below I have a way to start and end a path between nodes. Here is the error message Uncaught TypeError: Cannot set property '0' of undefined on line 15. Line 15 is nodes[x][y] = new GraphNode(x, y, row[x]); between the second for loop.

Here is my SSCCE.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>    
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type='text/javascript' src='graphstar.js'></script>
<script type="text/javascript">
    var board;
</script>
<script type='text/javascript' src='astar.js'></script>
<script type="text/javascript">
    $(document).ready(function()
{
        // UP to DOWN - 10 Tiles (Y)
        // LEFT to RIGHT - 15 Tiles (X)
        graph = new Graph([
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
        [1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1], 
        [1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 13, 13, 1], 
        [1, 13, 1, 1, 13, 1, 1, 13, 1, 13, 13, 1, 13, 13, 13, 1], 
        [1, 13, 13, 1, 1, 1, 13, 13, 1, 13, 13, 1, 1, 1, 13, 1], 
        [1, 13, 13, 1, 13, 1, 13, 13, 13, 13, 13, 1, 13, 13, 13, 1], 
        [1, 13, 13, 13, 13, 1, 13, 13, 13, 13, 13, 1, 13, 13, 13, 1], 
        [1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 1], 
        [1, 13, 1, 1, 1, 1, 13, 13, 13, 13, 1, 13, 13, 13, 13, 1], 
        [1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1], 
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        ]);
        //Let's do an example test.
        start = graph.nodes[1][2]; // X: 1, Y: 2
        end = graph.nodes[12][7]; // X: 12, Y: 7
        result = astar.search(graph.nodes, start, end);
    });
</script>
</head>
<body>
Loading... pathfinding. Look in Chrome Console/Firefox Firebug for more information.
</body>
</html>

As you can see, my game is jQuery. Also there is graphstar.js and astar.js. Don't worry about astar.js because it works fine. graphstar.js is the where my problem is. astar.js is where the nodes and such are laid out. graphstar.js is where the map is graphed.

See the whole graphstar.js here: http://pastebin.com/5AYRreip (Here is astar.js: http://pastebin.com/ee6PMzc3)

This is where it's laid out in graphstar.js:

function Graph(grid) {
    var nodes = [];
    var row, rowLength, len = grid.length;
    for (y = 0; y <= 15; y++) {
        row = grid[y];
        nodes[y] = new Array(15);
        for (x = 0; x <= 10; x++) {
            nodes[x][y] = new GraphNode(x, y, row[x]);
        }
    }
    this.input = grid;
    this.nodes = nodes;
}

So, as you can see... Y can be 10 or lower. X can be 15 or lower. However, I am getting this error.

Where as I am inputting end = graph.nodes[12][7]; // X: 12, Y: 7 SHOULD work because it is within the X and Y bounds... However I am having trouble even setting it up in the first place.

Why is it undefined?

UPDATE NEW

for (y = 0; y <= 10; y++) {

    row = grid[y];
    nodes[y] = new Array(15);

    for (x = 0; x <= 15; x++) {

        console.log("X: " + x + " Y: " + y);
        //console.log("Row: " + row[x]);
        nodes[x][y] = new GraphNode(x, y, row[x]);
    }
}

Solution

  • You're getting your axes mixed up.

    function Graph(grid) {
        var nodes = [];
        var row, rowLength, len = grid.length;
        for (y = 0; y <= 15; y++) {
            row = grid[y];
            // Here, you're indexing into `nodes` using `y`, so you're creating
            // an array at `nodes[0]` through `nodes[15]`
            nodes[y] = new Array(15);
            for (x = 0; x <= 10; x++) {
                // But here you're index into `nodes` using `x` in the first dimension,
                // so you're filling in `nodes[0][0]` through `nodes[10][15]`, not
                // `nodes[15][10]`.
                nodes[x][y] = new GraphNode(x, y, row[x]);
            }
        }
        this.input = grid;
        this.nodes = nodes;
    }
    

    Consequently, when you retrieve nodes[12], you get undefined because there's never been a value assigned to that index. Then you try to index into it, and get the error.

    You need to make sure you're consistently indexing into the outer array with one coordinate (x or y, whichever you prefer), and indexing into the inner arrays with the other coordinate (y or x, whichever you prefer).