Взаимодействие между соседними тд - PullRequest
0 голосов
/ 12 сентября 2018

Вопрос

Как я могу сравнить две соседние ячейки благодаря их координатам?

Документация, которая помогла мне

Я уже видел эти вопросы, они помогли мне, но они отличаются от моего случая:

  1. вопрос по stackOverflow
  2. вопрос по stackOverflow
  3. вопрос по stackOverflow
  4. Документация Mds для построения динамической таблицы

Код

У меня динамически сгенерированная таблица

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 row и cell имеют случайные значения

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

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

Последняя часть кода работает следующим образом:

  • Я сохраняю позицию selectedTd в двух разных переменных
  • Я создаю 2d массив 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

Интересующие функции в коде ручки имеют разные названия, но структура такая же, как вы видели в этом посте. Я изменил оригинальные имена, потому что я думаю, что это может быть более понятным с общими именами вместо имен, которые я выбираю

интересующие функции:

  • function fight(playerInFight) ---> function compare(selectedTd)
  • function mapGenerate(map) ---> function tableGenerate(MyTable)
  • mainTd и otherMainTd ---> character и characterTwo

CodepenHere

1 Ответ

0 голосов
/ 14 сентября 2018

Обновление: читая ваш код снова, я думаю, что я понял проблему.Вы сравниваете массив instance вместо их фактических значений.Посмотрите этот простой пример, чтобы проиллюстрировать проблему:

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);

Первоначальный ответ:

В вашем вопросе происходит довольно много вопросов, надеюсь, я правильно понял.

Что я сделал, так это создал Grid, вы передаете это измерениям, и он создаст массив для каждой ячейки в сетке.Затем он возвращает объект с некоторыми методами, которые вы можете использовать для взаимодействия с сеткой.Он имеет следующие методы:

  • 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);
...