2048: Странное поведение lowerRight на карте с lodash / fp - PullRequest
3 голосов

Следующий код является началом попытки сделать мою версию 2048 (игра) с использованием lodash- fp .Я привык к обычному lodash, но это мой первый контакт со вкусом fp.

Он реализует действие толкания вправо плиток одного ряда, используя две функции:

  • slide сдвигает строку вправо, если есть пустые пробелы (представленные значением 0).По сути, это равносильно размещению всех нулей слева.
  • merge объединяет пары смежных плиток одинакового значения, создавая пустое пространство и новый фрагмент двойного значения.(slide вызывается второй раз после merge для очистки нулей, которые могут возникнуть в результате этого шага).

Функции используют метод _.reduceRight, который перебирает плитки изсправа налево.

import _ from "lodash/fp";


let game = [[2, 2, 0, 0], [4, 0, 4, 0], [8, 0, 0, 8], [16, 16, 0, 0]]; // Sample state

let slide = _.flow(
  _.reduceRight(
    (v, acc) =>
      v === 0 ? [_.concat(acc[0], v), acc[1]] : [acc[0], _.concat(v, acc[1])],
    [[], []]
  ),
  _.flatten
);

let merge = _.flow(
  _.reduceRight(
    (v, acc) => {
      acc[0].unshift(v);
      if (acc[0].length === 2) {
        if (acc[0][0] === acc[0][1]) {
          acc[1] = _.concat(0, _.concat(acc[0][0] + acc[0][1], acc[1]));
          acc[0] = [];
        } else {
          acc[1] = _.concat(acc[0].pop(), acc[1]);
        }
      }
      return acc;
    },
    [[], []]
  ),
  _.flatten
);

// Moves one line
let moveLine = _.flow(
  slide,
  merge,
  slide
);

// Moves the 4 lines
let moveBoard = _.map(moveLine);

moveLine, кажется, работает хорошо.Например, moveLine(game[0]) преобразует [2, 2, 0, 0] в [0, 0, 0, 4].

Как ни странно, moveBoard(game) (который отображает moveLine на 4 строки) дает странный результат, увеличиваясь на каждой итерации, как если бырезультаты предыдущих шагов были добавлены:

[
  [0,0,0,4],
  [0,0,0,0,0,0,8,4],
  [0,0,0,0,0,0,0,0,0,16,8,4],
  [0,0,0,0,0,0,0,0,0,0,0,0,32,16,8,4]
]

Я вижу, что проблема связана с merge, но я действительно не вижу, что здесь происходит.

Ответы [ 2 ]

1 голос

Я открыл проблему GitHub с упрощенной версией проблемы: https://github.com/lodash/lodash/issues/4287.

Краткий ответ создателя Лодаша Джона-Дэвида Далтона:

При использовании композиции fp аккумулятор не создает новую функцию для каждой составленной функции уменьшения. Вот почему работает аккумуляторная версия без мутаций с помощью fp.concat ().

1 голос
/ 05 мая 2019

изменить move метод для удаления первых 4 элементов.

по какой-то странной причине для каждой итерации merge

в соответствии [1] ReduceRight в качестве предыдущего массива вэто

этот патч исправит это

let take = arr => arr.slice(0,4);

// Moves one line

let moveLine = _.flow(
  slide,
  merge,
  take
);

вот runkit с реализацией

https://runkit.com/naor-tedgi/5ccf0862b0da69001a7db546

...