【问题标题】:Immutable.js: Data structure to represent 2D game fieldImmutable.js:表示 2D 游戏领域的数据结构
【发布时间】:2016-04-13 16:09:30
【问题描述】:

我想知道我应该使用什么数据结构来表示方形游戏板(考虑每个单元格都可以有一些颜色)。最自然的想法是二维List,但是很难查询和更改。

所以,现在使用一个 Map,其中键是 ${x}.${y}(JS 中没有元组:(),值是代表颜色的字符串 像这样的:

Map([['0.0', 'red'], ['0.1', 'red'], ['1.0', 'blue'], ['1.1', 'red']])

这样的数据结构可以吗?在 Immutable.js 方面有没有更好的解决方案?

【问题讨论】:

    标签: javascript immutability immutable.js


    【解决方案1】:

    我也在构建自己的一些 2D 游戏板,我也遇到了同样的问题。我的解决方案是Record

    它只是看起来像一个对象,也表现得像一个对象。但是对于 vanilla 对象,您不能执行以下映射字典的事情。

    const dict = {};
    
    const key1 = { row: 0, col: 1 };
    const value1 = { some: 'value' };
    
    dict[key1] = value; // will not work
    

    这就是我想要的,我试图使映射尽可能简单地处理。使用 Immutable.js 中的 RecordMap,您可以执行以下操作。

    import { Map, Record } from 'immutable';
    
    const dict = Map();
    const Pos = Record({ row: 0, col: 0 }); // some initial value.
    const Val = Record({ some: 'value' }); // same here.
    
    const key1 = new Pos({ row: 0, col: 1 });
    const value1 = new Val({ some: 'value' });
    
    dict = dict.set(key1, value1); // works like you wish
    

    您可以阅读官方文档以获取更多信息。也许你有更好的解决方案,请告诉我:)。

    【讨论】:

    • 不错的答案!我可以比较两条记录吗?
    • 当然可以,检查 Immutable.is()
    • 我想把这个添加到答案中是有意义的
    • 不错。但也许一个OrderedMap 来保证物品的顺序?或者你如何打印矩阵?我会使用两个 for 循环,所以我需要保证。
    【解决方案2】:

    有没有理由不能像这样使用二维数组:

    let square = [
        ['red', 'green', 'blue'],
        ['orange', 'red', 'blue'],
        ['red', 'blue', 'blue']
    ];
    

    然后你就可以将上面的数据结构添加到你的地图中了。

    所以要访问中间图块,您只需使用数组的[1][1] 索引。

    【讨论】:

    • >在 Immutable.js 方面有没有更好的解决方案?
    • 我确定有。您刚刚询问了数据结构。我就是这样做的。问题是,如果这是您所说的“游戏板”,您为什么希望它是不可变的?它不会在某个时候改变状态吗?
    【解决方案3】:

    我很好奇为什么您认为 List of Lists 很难查询和更改。您可以使用长度为 2 的数组作为 [x, y] 对,并将其传递给 getInsetInupdateIn 方法。

    let grid = Immutable.toJS([
        ['red', 'green'],
        ['blue', 'yellow']
    ]);
    
    grid.getIn([0, 1]); // => 'green';
    grid = grid.setIn([0, 1], 'purple');
    grid.getIn([0, 1]); // => 'purple';
    grid = grid.updateIn([0, 0], cell => cell.toUpperCase());
    grid.getIn([0, 0]); // => 'RED';
    

    使用map(...) 可以很容易地将某些功能应用于网格中的每个单元格:

    grid.map((row, x) => row.map(cell, y) => x + cell + y);
    grid.get([1, 1]); // => '1yellow1'
    

    可能比使用 Map 更棘手的事情是尝试查找值的坐标。

    const x = grid.findIndex(row => row.contains('blue')); // => 1
    const y = grid.get(x).indexOf('blue'); // => 0
    grid.get([x, y]); // => blue
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 2011-06-30
      相关资源
      最近更新 更多