Unity3D是循环使用多维数组的最佳方式



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

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]);
}
}
}

然后我就陷入了困境。我真的不知道还能做什么。

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

无更改:

对用户输入进行排序:

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),但由于输入是排序的,因此平均情况会更好。

演示

有了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是用户选择的值的数量(不考虑测试对象是否包含特定属性名称所需的时间。通常假设为常数)。

演示

最新更新