Неожиданное поведение indexOf с многомерным массивом - PullRequest
0 голосов
/ 13 июня 2019

Я пытаюсь сделать классическую игру со змеями в p5.js. У меня есть объект-змея, и я храню местоположения его тела в 2-мерном массиве this.data, где каждый элемент хранит значение x и значение y (с индексами 0 и 1 соответственно). Когда змея движется, я вставляю новые позиции в массив.

Я столкнулся с проблемой, когда попытался определить, столкнулась ли змея сама с собой. Я попытался проверить, была ли его текущая позиция уже в массиве, используя indexOf, мотивируя это тем, что если бы новое местоположение было открыто, это происходило бы только один раз в массиве, при индексе на единицу меньше, чем длина массива. В противном случае, если местоположение уже существует в другом месте массива (что указывает на то, что змея столкнулась с самим собой), оно вернет значение, меньшее длины минус единица.

Однако, похоже, этого не происходит.

function Snake()
{
    this.x; //x-coordinate of head
    this.y; //y-coordinate of head
    this.dx; //velocity in x-direction
    this.dy; //velocity in y-direction
    this.length; //length of snake
    this.data; //stores all locations snake occupies
    this.alive = 1; //is the snake alive?

    this.update = function(board)
    {
        if (this.alive)//update head position
        {
            this.x += this.dx;
            this.y += this.dy;

            let tempCoords = [this.x,this.y];
            this.data.push(tempCoords);

            while (this.data.length > this.length) //janky
            {
                this.data = this.data.slice(1);
            }

            if (this.data.indexOf(tempCoords) + 1 != this.data.length) //make sure snake hasn't hit itself
            {
                this.alive = 0;
            }
        }

    }
}

Последний оператор if всегда оценивает false, даже если змея пересекает себя. Судя по проведенному мною тестированию, эта проблема возникает при использовании indexOf для многомерных массивов. Какие есть решения этой проблемы?

Ответы [ 2 ]

0 голосов
/ 13 июня 2019

По сути, у вас есть следующие данные, и вы хотите увидеть, совпадают ли данные в head с любым из элементов в points

var points = [[1,1],[1,2],[1,3]]
var head = [1,2]

Вы можете проверить любые совпадения вмассив, используя Array.some() как это:

var overlap = points.some(p => p[0] === head[0] && p[1] === head[1])

var points = [[1,1],[1,2],[1,3]]
var head = [1,2]

var overlap = points.some(p => p[0] === head[0] && p[1] === head[1])

console.log(overlap)
0 голосов
/ 13 июня 2019

indexOf использует проверку на равенство для поиска индекса, а

  [0, 0] === [0, 0]

равно false , поскольку объекты (и массивы являются объектами) сравниваются по ссылке (и выдействительно есть два разных массива).Чтобы сравнить их по их внутренним значениям, вы должны вручную сравнить x и y друг с другом:

  const collides = this.data.some(coords => coords[0] === this.x && coords[1] === this.y);
...