//尝试通路
function applyChild(parent) {
const child = getChild(parent)
const newChild = child.filter(c => {
const newCost = c.cost + parent.totalCost
if (c.parent.length == 0) {
c.parent.push(parent)
c.totalCost = newCost
} else if (c.parent.find(i => i == parent) && newCost >= c.totalCost) {
return false //终止走回路
} else {
if (c.totalCost == newCost) {
c.parent.push(parent)
} else if (c.totalCost > newCost) {
c.totalCost = newCost
c.parent = [parent]
} else {
return false //终止消耗过高
}
}
return true
})
return newChild
}
//结果逆推顺序
function getRoute({ x, y, value, parent }, result) {
parent = parent.filter(i => !result.find(n => n.x == i.x && n.y == i.y))//不走回路
result.push({ x, y, value })
if (!(start.x == x && start.y == y)) {
parent.forEach(_parent => getRoute(_parent, [...result]))
} else {
routes.push(result)
}
}
//输入数组
let m = [
[2, 0, 0, 0, 2, 2],
[0, 0, 2, 0, 3, 2],
[0, 2, 4, 0, 2, 2],
[0, 0, 2, 2, 2, 3],
[2, 0, 0, 2, 3, 2],
[3, 2, 0, 1, 3, 2]
];
let size = m.length;
let record = m.map((i, y) => i.map((m, x) => ({ x: x, y: y, value: m, cost: (m == 2) * 1, totalCost: 0, parent: [] })));
let flat = record.flat();
let start = flat.find(i => i.value == 1);
let end = flat.find(i => i.value == 4);
//获取可通过的周围四个点
function getChild({ x, y }) {
return [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].filter(([x, y]) => { return (x < size && y < size && x >= 0 && y >= 0 && !(x == end.x && y == end.y)) }).map(([X, Y]) => flat.find(({ x, y }) => x == X && y == Y))
}
let result = applyChild(start);
//循环遍历通路
while (result.length > 0) {
result = result.map(c => applyChild(c)).flat()
}
//遍历结果
result = getChild(end)
let routes = []
result.forEach(i => { getRoute(i, []) })
//最终结果,[步数,战斗次数,宝箱数]
routes.map(i => [i.length, i.filter(i => i.value == 2).length, i.filter(i => i.value == 3).length])
最终还是一个人承担了所有😣