以下代码是尝试使用lodash- fp 制作我的2048版本(游戏)的开始。我已经习惯了定期聊天,但这是我第一次接触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
,但我真的看不到这里是怎么回事。
答案 0 :(得分:1)
更改move
方法以删除前4个元素。
出于某种奇怪的原因,merge
的每次迭代
ReduceRight的acc [1]作为其中的上一个数组
此修补程序将对其进行修复
let take = arr => arr.slice(0,4);
// Moves one line
let moveLine = _.flow(
slide,
merge,
take
);
这是带有实现的Runkit
答案 1 :(得分:1)
我打开了GitHub问题,其中包含问题的简化版本:https://github.com/lodash/lodash/issues/4287。
lodash的创建者John-David Dalton给出的简短答案:
使用fp合成,累加器不会为每个组成的reduce函数创建新鲜的对象。这就是为什么使用fp.concat()创建无突变版本的累加器的原因。