【问题标题】:Unity3D the best way to loop through multiple dimension arraysUnity3D 循环遍历多维数组的最佳方式
【发布时间】:2014-01-07 13:50:39
【问题描述】:

我正在开发一个具有获胜组合数组的游戏:

var allwinning = [
['000','010','020'],
['000','100','200'],
['000','001','002'],
['000','101','202'],
['000','011','022'],
['000','110','220']];

玩家需要随机选择 3 个以上的数字。如果所有数字都在allwinning 中的任意组合之内,则玩家获胜。

例如,如果玩家选择'111','110','000','220',玩家将获胜,因为allwinning[5] 的组合是['000','110','220']

我的问题是,完成这个获胜循环的最佳方法是什么?我想不出这样做的最佳方法。

目前,我有一个 playerpick 数组来保存玩家选择的内容和 possiblewin 数组:

var playerpick = new Array(['111','110','000','220']);
var playerpicksingle = playerpick[0];
var possiblewin = new Array([]);

然后我通过一个循环首先捕获可能的获胜组合:

for(var i=0 ; i < allwinning.length - 1 ; i++)
    {
        for(var j=0 ; j <3 ; j++)
        {
            if(allwinning[i][j]==playerpicksingle)
            {
            possiblewin.Push(allwinning[i]);
            }
        }
    }

然后我被困在这一点上。我真的不知道还能做什么。

【问题讨论】:

  • 那么,到目前为止你有什么,是什么让你认为这不是最佳方式?
  • @FelixKling 阅读了我的编辑。谢谢!

标签: arrays unity3d unityscript


【解决方案1】:

我可以想到两种方法。一种要求您更改数据结构,另一种则不需要。

没有变化:

对用户输入进行排序:

pickedNumbers.sort();

然后开始比较。通过预先对值进行排序,您知道何时可以退出并继续下一组数字,即您可以提前退出,而不必比较所有值(在平均情况下)。

function wins(picked, winning) {
    var winningSet = [];

    for (var i = 0; i < winning.length && winningSet.length < 3; i++) {
        var set = winning[i];
        winningSet = [];
        var j = 0;
        var k = 0;
        while (j < set.length && k < picked.length && winningSet.length < 3) {
            if (picked[k] === set[j]) {
                winningSet.push(set[j]);
                j++; // advance to next element in winning set
            } else if (picked[k] > set[j]) {
                // continue with the next set 
                break;
            }
            // maybe the next element in players picks will match
            k++;
        }
    }
    return winningSet.length === 3 ? winningSet : false;
}

这个解决方案最坏的情况是O(n*m*l),但是由于输入是排序的,平均情况会更好。

DEMO

使用Array#someArray#every,代码变得更加简洁,尽管它失去了使用排序输入的优势。如果你的数组很小,它不会有所作为:

function wins(picked, winning) {
    return winning.some(function(set) {
        return set.every(function(val) {
            return picked.indexOf(val) !== -1;
        });
    });
}

它也不会给你匹配的实际数字。运行时是一样的。


第二种方法是构建某种 trie,而不是使用数组数组:

var allwinning = {
    '000': {
        '010': {
            '020': true
        },
        '100': {
            '200': true
        },
        // ...
    }
};

结构也应该排序,即一个级别的键都小于其子级别的键等。

也对用户输入进行排序并对其进行迭代。每当您找到匹配的键时,您就会更深一层,直到找到三个匹配项:

function wins(picked, winning) {
    var winningSet = [];
    for (var i = 0; i < picked.length && winningSet.length < 3; i++) {
        if (picked[i] in winning) {
            winningSet.push(picked[i]);
            winning = winning[picked[i]];
        }
    }
    return winningSet.length === 3 ? winningSet : false;
}

此解决方案的最坏情况是O(n),其中n 是用户选择的值的数量(不考虑测试对象是否包含特定属性名称所需的时间。通常这是假定为常数)。

DEMO

【讨论】:

  • 好的,经过大量分析,我想我明白了。我认为您的第一种方法对我有用。现在我只需要对我所有的数组进行排序。谢谢!
猜你喜欢
  • 2013-04-01
  • 2010-11-03
  • 2012-04-21
  • 2011-01-02
相关资源
最近更新 更多