相邻td之间的相互作用

时间:2018-09-12 10:45:32

标签: javascript jquery arrays html-table

问题

我如何比较两个相邻单元格的坐标?

对我有帮助的文档

我已经看到了这些问题,它们帮助了我,但与我的情况有所不同:

  1. question on stackOverflow
  2. question on stackOverflow
  3. question on stackOverflow
  4. Mds documentation to build a dynamic table

代码

我有一个动态生成的表

function tableGenerate(Mytable){
        for(var i = 0; i < myTable.length; i++) {
            var innerArrayLength = myTable[i].length;
            for(var j = 0; j<innerArrayLength; j++){
                if(myTable[i][j] === 0){
                    myTable[i][j]="x";
                }else{
                    myTable[i][j]="y";
                };
            };
            $("#aTable").append("<tr><td>"+ myTable[i].join('</td><td>') + "</td></tr>")    
        }
}  

关于actualPosition rowcell中感兴趣的单元格(两个全局变量)具有随机值

var mainTd = {
     name: 'interestedValue',
     actualPosition:{
            row: 5,
            cell: 4
          }
};

var otherMainTd = {
     actualPosition:{
            row: 2,
            cell: 3
          }
};

代码的最后部分是这样工作的:

  • 我将selectedTd的位置保存在两个不同的变量中
  • 我创建二维数组directions,并使用与selectedTd相对的近单元格的坐标
  • 输入第一个if,比较两个单元格。如果其中一个坐标相同,则输入最后一个if

function compare(selectedTd) {
    let tdRow = selectedTd.actualPosition.row;
    let tdCell = selectedTd.actualPosition.cell;
    let directions = [
        [tdRow - 1, tdCell],
        [tdRow + 1, tdCell],
        [tdRow, tdCell + 1],
        [tdRow, tdCell - 1]
    ]; //these are the TD near the mainTd, the one i need to compare to the others

    let tdToCompare = [];

    if (selectedTd.name === 'interestedValue') {
        tdToCompare = [otherMainTd.actualPosition.row, otherMainTd.actualPosition.cell];
        for (let i = 0; i < directions.length; i++) {
            if (directions[i] == tdToCompare) {
                console.log('you are here');
            }
        }
    } else {
        tdToCompare = [mainTd.actualPosition.row, mainTd.actualPosition.cell];
        for (let i = 0; i < directions.length; i++) {
            if (directions[i] === tdToCompare) {
                console.log('you are here');
            }
        }
    }
};

现在主要的问题是:我读取了坐标,将其存储在2个数组中,可以读取它们,但无法输入if语句。

这就是我要实现的:将blackTd的坐标与红色边界td的坐标进行比较。

enter image description here

Codepen

codepen中感兴趣的函数具有不同的名称,但是结构与您在本文中看到的相同。我更改了原始名称,因为我认为使用通用名称而不是我选择的名称会更清楚。

感兴趣的功能是:

  • function fight(playerInFight) ---> function compare(selectedTd)
  • function mapGenerate(map) ---> function tableGenerate(MyTable)
  • mainTdotherMainTd ---> charactercharacterTwo

CodepenHere

1 个答案:

答案 0 :(得分:1)

更新: 再次阅读您的代码,我想我已经解决了问题。您正在比较数组 instances 而不是它们的实际值。请看以下简单示例来说明问题:

var a = [1];
var b = [1];

console.log(a===b);

您需要在代码中执行的操作是:

 if (selectedTd.name === 'interestedValue') {
    tdToCompare = [otherMainTd.actualPosition.row, otherMainTd.actualPosition.cell];
    for (let i = 0; i < directions.length; i++) {
        if (
          directions[i][0] === tdToCompare[0] &&
          directions[i][1] === tdToCompare[1]
        ) {
            console.log('you are here');
        }
    }
} else {
    tdToCompare = [mainTd.actualPosition.row, mainTd.actualPosition.cell];
    for (let i = 0; i < directions.length; i++) {
        if (
          directions[i][0] === tdToCompare[0] &&
          directions[i][1] === tdToCompare[1]
        ) {
            console.log('you are here');
        }
    }
}

现在,它会检查值是否匹配,从而检查单元格是否匹配。


建议:

如果我是你,我会写一些不同的方法。下面是我的处理方法。

function compare(selectedTd) {
  const
    // Use destructuring assignemnt to get the row and cell. Since these are 
    // values that won't be changed in the method declare them as "const". Also
    // drop the "td" prefix, it doesn't add anything useful to the name.
    // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment  
    { row, cell } = selectedTd.actualPosition,
    
    // Directions can also be a const, it will not be reassigned in the method.
    directions = [
        [row - 1, cell],
        [row + 1, cell],
        [row, cell + 1],
        [row, cell - 1]
    ],
    // A few things happens in this line:
    // - It is a destructuring assignment where the names are changed. In this case 
    //   row and cell are already assigned so it is necessary to give them another name.
    // - Don't put the row and cell in an array. You will have to access the actual values
    //   anyway as you can't compare the array instances.
    // - Instead of doing this in the if…else you had, decide here which cell you want to
    //   look for. It means the rest of the method can be written without wrapping any
    //   logic in an if…else making it less complex.
    { row: referenceRow, cell: referenceCell } = (selectedTd.name === 'interestedValue')
      ? otherMainTd.actualPosition
      : mainTd.actualPosition,
    
    // Use find instead of a for loop. The find will stop as soon as it finds a match. The
    // for loop you had kept evaluating direction items even if the first one was already
    // a match.
    // The "([row,cell])" is the signature of the callback method for the find. This too is
    // a destructuring assignment only this time with one of the arrays of the directions
    // array. The first array item will be named "row" and the second item "cell". These
    // variable names don't clash with those declared at the top of this method as this
    // is a new scope.
    // The current directions entry is a match when the row and cell values match.
    matchingNeighbor = directions.find(([row, cell]) => row === referenceRow && cell === referenceCell);
    
    // "find" returns undefined when no match was found. So when match is NOT unddefined
    // it means directions contained the cell you were looking for.
    if (matchingNeighbor !== undefined) {
      console.log('you are here');    
    }
};

const
  mainTd = {
    name: 'interestedValue',
    actualPosition: {
      cell: 1,
      row: 1
    }
  },
  otherMainTd = {
    actualPosition: {
      cell: 0,
      row: 1
    }
  };

compare(mainTd);


原始答案:

您的问题有很多内容,希望我能正确理解。

我要做的是创建一个网格,将其传递给尺寸,它将为网格中的每个单元创建数组。然后,它使用一些可用于与网格进行交互的方法返回一个对象。它具有以下方法:

  • cellAtCoordinate:向其传递X和Y坐标,然后返回单元格。
  • isSameLocation:将两个单元格传递给它,并检查这些单元格是否在同一位置。
  • neighborsForCoordinate:向其传递X和Y坐标,并返回一个数组,该数组包含上,下,右,左(如果存在)的单元格。

所有这些使比较方法变得更易于管理。现在,获取邻居只是一个电话,检查两个单元是否匹配也是如此。

就像我说的那样,我希望这是您想要实现的目标。如果我错了,并且需要进一步解释,请告诉我。

/**
 * Creates grid with the provided dimensions. The cell at the top left corner
 * is at coordinate (0,0). The method returns an object with the following 
 * three methods:
 * - cellAtCoordinate
 * - isSameLocation
 * - neighborsForCoordinate
 */
function Grid(width, height) {
  if (width === 0 || height === 0) {
    throw 'Invalid grid size';
  }
  
  const
    // Create an array, each item will represent a cell. The cells in the
    // array are laid out per row.
    cells = Array.from(Array(width * height), (value, index) => ({
      x: index % width,
      y: Math.floor(index / height)
    }));
    
  function cellAtCoordinate(x, y) {
    // Make sure we don't consider invalid coordinate
    if (x >= width || y >= height || x < 0 || y < 0) {
      return null;
    }

    // To get the cell at the coordinate we need to calculate the Y offset
    // by multiplying the Y coordinate with the width, these are the cells
    // to "skip" in order to get to the right row.
    return cells[(y * width) + x];
  }
  
  function isSameLocation(cellA, cellB) {
    return (
      cellA.x === cellB.x &&
      cellA.y === cellB.y
    );
  }

  function neighborsForCoordinate(x, y) {
    // Make sure we don't consider invalid coordinate
    if (x >= width || y >= height || x < 0 || y < 0) {

      return null;
    }
    const
      result = [];

    // Check if there is a cell above.
    if (y > 0) result.push(cellAtCoordinate(x, y - 1));
    // Check if there is a cel to the right
    if (x < width) result.push(cellAtCoordinate(x + 1, y));
    // Check if there is a cell below.
    if (y < height) result.push(cellAtCoordinate(x, y + 1));
    // Check if there is a cell to the left.
    if (x > 0) result.push(cellAtCoordinate(x - 1, y));

    return result;
  }

  return {
    cellAtCoordinate,
    isSameLocation,
    neighborsForCoordinate
  }
}

function compareCells(grid, selectedCell) {
  const
    // Get the neighbors for the selected cell.
    neighbors = grid.neighborsForCoordinate(selectedCell.x, selectedCell.y);
    compareAgainst = (selectedCell.name === 'interestedValue')
      ? otherMainTd
      : mainTd;
      
    // In the neighbors, find the cell with the same location as the cell
    // we want to find.
    const
      match = neighbors.find(neighbor => grid.isSameLocation(neighbor, compareAgainst));
      
    // When match is NOT undefined it means the compareAgainst cell is
    // a neighbor of the selected cell.
    if (match !== undefined) {
      console.log(`You are there at (${match.x},${match.y})`);
    } else {
      console.log('You are not there yet');
    }      
}

// Create a grid which is 3 by 3.
const
  myGrid = Grid(3, 3),
  // Place the main TD here:
  // - | X | -
  // - | - | -
  // - | - | -
  mainTd = {
    name: 'interestedValue',
    x: 1,
    y: 0
  },
  // Place the other TD here:
  // - | - | -
  // Y | - | -
  // - | - | -  
  otherMainTd = {
    x: 0,
    y: 1
  };


// Check if the mainTd is in a cell next to the otherMainTd. It is not
// as the neighboring cells are:
// N | X | N
// Y | N | -
// - | - | -

compareCells(myGrid, mainTd);
// Move the mainTd to the center of the grid
// - | - | -
// Y | X | -
// - | - | -
mainTd.y = 1;

// Compare again, now the main TD is next the the other.
// -  | N | -
// YN | X | N
// -  | N | -
compareCells(myGrid, mainTd);