我正在为我的网站armyfight进行军队斗争。可能有数百万单位的战斗。我正在寻找更好的单位定位。在jsfiddle中就是一个例子。
var enemy = {
2: {
3: {} // object inside with unit data
},
5: {
6: {}
}
}
var ally = {
4: {
3: {}
}
}
function unit_searches_for_target(y, x) {
var closest_y = iterate_Y(y);
var unit_target = iterate_X(closest_y, x);
return unit_target;
}
// Searches for closest target at Y axis
function iterate_Y(y) {
if (_.has(target, y)) {
return y;
} else {
var y = parseInt(y);
for (var i = 1; i < 300; i++) {
// If y == 4, it checks 4+1=5 (positive side)
if (_.has(target, String(y + i))) {
return (y+i);
// Else if y == 4, it checks 4-1=3 (negative side)
} else if (_.has(target, String(y - i))) {
return (y-i);
}
}
}
// if didn't find anything, just returns same y as given
return y;
};
// Searches for closest target at X axis
function iterate_X(y, x) {
if (_.has(target[y], x)) {
return {y: y, x: x};
} else {
var x = parseInt(x);
for (var i = 1; i < 300; i++) {
// If x == 4, it checks 4+1=5 (positive side)
if (_.has(target[y], String(x + i))) {
return {y: y, x: x + i};
// Else if x == 4, it checks 4-1=3 (negative side)
} else if (_.has(target[y], String(x - i))) {
return {y: y, x: x - i};
}
}
}
// if didn't find anything, just returns same x as given
return {y: y, x: x};
};
这里首先在Y轴上迭代,然后在X轴上迭代。但在不同的军队阵地上,它会产生错误的结果
在此示例中,单位通过简单迭代来查找目标。对于百万单位的大规模军队斗争来说,这不是很好
最好的是迭代这里,当迭代过程更快,导致第一次成功:
function iterate_X(y, x) {
return _.find(enemy[y], function (value, key) { return parseInt(key) >= x });
}
但是这个迭代仅适用于0..100或99..100,但不是100..0,所以我不能以反向模式迭代对象。
所以如果盟友是{5: {10: {}, 99: {}}
敌人在{5: {100: {}}}
,敌人单位会找到最接近的盟友[5,10],而不是[5,99]。如果它是一个从100向后迭代的数组,那么它将是第一次成功。但是我对assotiative数组有问题,可以反向迭代吗?
请问结构有什么建议吗?也许改变从对象到数组的单位结构或混合?但后来我遇到了关联数组的问题。我正在寻找关于结构的解释或示例以及针对单位目标的更快迭代。
我也在寻找网站,在那里我可以问这些重要的逻辑问题?我有更多。
答案 0 :(得分:-1)
我会避免使用&#34; find&#34;出于性能原因,请使用某种索引访问。
例如,可以将您的单位放入哈希:
此哈希的键可以是字符串xcoord +&#34;:&#34; + ycord
此哈希值可以是对象的哈希值,由某个唯一的单位ID键入。 那么,你可以通过检查当前单元格和周围8个单元格中的内容来搜索单元的邻居
我尝试了下面的代码,它在1秒内找到所有1M单位的所有邻居。
var units = {}
for(var i=0; i<1000000; i++) {
var x = Math.floor(Math.random()*400);
var y = Math.floor(Math.random()*400);
var idx = x+":"+y;
if(!units[idx])
units[idx] = {};
units[idx][i] = {
id: i,
x: x,
y: y,
//... other attributes of your unit
};
};
// find neighbours for each unit;
console.log('Started lookups');
var start = new Date().getTime();
var keys = Object.keys(units);
for(var i=0; i<keys.length; i++) {
var neighbours = findNeighbours(units[keys[i]]);
}
var finish = new Date().getTime();
console.log('Finished lookups in '+(finish-start));
function findNeighbours(unit) {
var res = [];
// check who is in all 9 cells
// x x x
// x unit x
// x x x
for(var i=0; i<3; i++) {
for(var j=0; j<3; j++) {
var idx = (unit.x+i-1)+":"+(unit.y+j-1);
var unitsInCell = units[idx];
if(unitsInCell) {
var keys = Object.keys(unitsInCell);
for(var j = 0; j<keys.length; j++)
res.push(unitsInCell[keys[j]]);
}
}
}
}