Question

I've made a Knight's Tour game in javascript. You can try it here. (Particularly for reproducing the error)

The error I'm having so much trouble finding reads

Uncaught TypeError: Cannot read property 'innerHTML' of undefined

but I'm not sure why it's undefined. I have a table with 64 cells (making a chessboard). They're all built as plain and empty

<table border=1 style="border: 1px solid black; table-layout: fixed;">
  <tr>
    <td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr><tr>
    ...

This is the only table on the page. I use javascript to retrieve all of the td elements and I iterate through them adding ids, classes, background color and onclick eventListeners for gameplay.

var tds;
window.onload = function() {
    tds = document.getElementsByTagName("td");
    for (var i = 0; i < tds.length; i++) {
        if (typeof window.addEventListener === 'function') {
            (function (td) {
                ...
                td.addEventListener('click', function() {
                    ...

There seems to be a few different cells that repeatably have this error occur. Sometimes I can get the individual cell to produce an error, other times I can't. One repeatable example is to move first on the bottom row, second to last cell, and then try to move onto the cell two up and one right from it along the side.

I read the innerHTML attribute frequently inside the onclick. I refer to the global tds array of td elements. Here are basically all forms of myself accessing them.

if (tds[cell].innerHTML === "") {
if (tds[n].innerHTML === "♞") {
tds[cell].innerHTML = "♞";
tds[target].innerHTML = "♘";
td.innerHTML = "♞";

I really thought I had it figured out when I was reading about the difference between declaring a variable using var and when not using it, but I couldn't figure out a single var that was causing this error. Any help would be appreciated.

Was it helpful?

Solution

The boundary test:

 if (x > 0 && y < 6) { //bottom right

isn't right, the x condition should be x < 7; it's the right hand column you are trying to avoid not the left.

To avoid all that duplication (and subsequent likelihood of a trivial copy-paste-edit error like this), I recommend doing the position calculation in x/y co-ordinate terms and then calculating the cell index from there instead of working in cell indices and checking each boundary separately. And actually, tables have rows/cells properties so you don't have to do the cell index calculation either. For example:

var knight_moves = [[-1, -2], [1, -2], [-2, -1], [2, -1], [-2, 1], [2, 1], [-1, 2], [1, 2]];

for (var i= knight_moves.length; i-->0;) {
    var other_x = x + knight_moves[i][0];
    var other_y = y + knight_moves[i][1];
    if (other_x>=0 && other_x<8 && other_y>=0 && other_y<8) {
        var cell = table.rows[other_y].cells[other_x];
        if (cell.innerHTML=='♞') ...
    }
}

OTHER TIPS

The problem is that n at that point is equal to 64. The total length of the tds array is 64 (or 0 to 63) and it's generating an error because element that n represents is outside the range of the array.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top