Способ определения типа стен и глубины вложенности областей карты. Входные данные - карта описанная как пустые и заполненные области. Задача - определить границы стен, их ориентацию, углы и прочее. Также выделить замкнутые области и определить глубину их вложенности (на самом деле интереснее определить чётность этих областей)
Легенда:
- □ ═║ ╔╦╗ ╠╬╣ ╚╩╝стены
- 1-9области по уровню вложенности
Начальные данные:
Итоговая карта:
Исходный код (открыть)
module.exports = function (rawMap) {
rawMap = rawMap.map(function (line) {
return line.split("");
});
var len = rawMap[0].length;
var hgh = rawMap.length;
var zones = [];
var walls = [];
var map = [];
rawMap.forEach(function (row, y) {
map[y] = [];
row.forEach(function (cell, x) {
map[y][x] = {
type: cell == "*" ? "wall" : "floor",
x: x,
y: y,
level: 99
};
});
});
map[0][0].level = 1;
zones.push(map[0][0]);
var checkZone = function (x, y, type, level) {
if (x < 0 || y < 0 || x >= len || y >= hgh) return false;
var zone = map[y][x];
if (zone.type != type) level++;
if (zone.level > level) {
zone.level = level;
if (zone.type == type) zones.unshift(zone);
else zones.push(zone);
}
return zone.type == type;
};
var checkNeibs = function (zone) {
var closed = true;
[[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]].forEach(function (move) {
closed = checkZone(zone.x + move[0], zone.y + move[1], zone.type, zone.level) && closed;
});
zone.closed = closed;
if (!zone.closed) {
if (zone.type == "wall") walls.push(zone);
}
};
while (zones.length) checkNeibs(zones.shift());
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var wallConfig = ["□", "═", "║", "╗", "═", "═", "╔", "╦", "║", "╝", "║", "╣", "╚", "╩", "╠", "╬"];
var top = 1 << 3;
var right = 1 << 2;
var bottom = 1 << 1;
var left = 1;
walls.map(function (wall) {
wall.left = map[wall.y][wall.x - 1];
wall.right = map[wall.y][wall.x + 1];
wall.top = map[wall.y - 1][wall.x];
wall.bottom = map[wall.y + 1][wall.x];
wall.left = wall.left.type == "wall" && !wall.left.closed;
wall.right = wall.right.type == "wall" && !wall.right.closed;
wall.top = wall.top.type == "wall" && !wall.top.closed;
wall.bottom = wall.bottom.type == "wall" && !wall.bottom.closed;
var type = 0;
type += wall.top ? top : 0;
type += wall.right ? right : 0;
type += wall.bottom ? bottom : 0;
type += wall.left ? left : 0;
wall.typeNum = type;
return wall;
}).forEach(function (wall) {
var neib;
if (wall.typeNum == 14) { // ╠
neib = map[wall.y][wall.x + 1];
if (neib.typeNum == 11) {
wall.typeNum = 8;
neib.typeNum = 8;
}
} else if (wall.typeNum == 11) { // ╣
neib = map[wall.y][wall.x - 1];
if (neib.typeNum == 14) {
wall.typeNum = 10;
neib.typeNum = 10;
}
} else if (wall.typeNum == 7) { // ╦
neib = map[wall.y + 1][wall.x];
if (neib.typeNum == 13) {
wall.typeNum = 5;
neib.typeNum = 5;
}
} else if (wall.typeNum == 13) { // ╩
neib = map[wall.y - 1][wall.x];
if (neib.typeNum == 7) {
wall.typeNum = 5;
neib.typeNum = 5;
}
}
wall.symbol = wallConfig[wall.typeNum];
});
return map;
}
Комментариев нет:
Отправить комментарий