3

下面的代码是尝试使用 lodash- fp制作我的 2048 版本(游戏)的开始。我习惯了常规的 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,但我真的看不到这里发生了什么。

4

2 回答 2

1

我已经用问题的简化版本打开了一个 GitHub 问题:https ://github.com/lodash/lodash/issues/4287 。

lodash 的创造者 John-David Dalton 给出的简短回答:

使用 fp 组合,累加器不会为每个组合的 reduce 函数创建新的。这就是为什么使用 fp.concat() 创建累加器的无突变版本的原因。

于 2019-05-06T17:43:21.897 回答
1

更改move 方法以删除前 4 个元素。

每次迭代都有一些奇怪的原因merge

ReduceRight 的 acc[1] 作为其中的前一个数组

这个补丁将修复它

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

// Moves one line

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

这是一个带有实现的runkit

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

于 2019-05-05T19:56:34.157 回答