diff options
| author | Georgios Andreadis <info@gandreadis.com> | 2020-06-29 15:47:09 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2020-08-24 16:08:41 +0200 |
| commit | 90fae26aa4bd0e0eb3272ff6e6524060e9004fbb (patch) | |
| tree | bf6943882f5fa5f3114c01fc571503c79ee1056d /frontend/src/util/tile-calculations.js | |
| parent | 7032a007d4431f5a0c4c5e2d3f3bd20462d49950 (diff) | |
Prepare frontend repository for monorepo
This change prepares the frontend Git repository for the monorepo
residing at https://github.com/atlarge-research.com/opendc. To
accomodate for this, we move all files into a frontend subdirectory.
Diffstat (limited to 'frontend/src/util/tile-calculations.js')
| -rw-r--r-- | frontend/src/util/tile-calculations.js | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/frontend/src/util/tile-calculations.js b/frontend/src/util/tile-calculations.js new file mode 100644 index 00000000..95886eeb --- /dev/null +++ b/frontend/src/util/tile-calculations.js @@ -0,0 +1,261 @@ +export function deriveWallLocations(tiles) { + const { verticalWalls, horizontalWalls } = getWallSegments(tiles); + return mergeWallSegments(verticalWalls, horizontalWalls); +} + +function getWallSegments(tiles) { + const verticalWalls = {}; + const horizontalWalls = {}; + + tiles.forEach(tile => { + const x = tile.positionX, + y = tile.positionY; + + for (let dX = -1; dX <= 1; dX++) { + for (let dY = -1; dY <= 1; dY++) { + if (Math.abs(dX) === Math.abs(dY)) { + continue; + } + + let doInsert = true; + for (let tileIndex in tiles) { + if ( + tiles[tileIndex].positionX === x + dX && + tiles[tileIndex].positionY === y + dY + ) { + doInsert = false; + break; + } + } + if (!doInsert) { + continue; + } + + if (dX === -1) { + if (verticalWalls[x] === undefined) { + verticalWalls[x] = []; + } + if (verticalWalls[x].indexOf(y) === -1) { + verticalWalls[x].push(y); + } + } else if (dX === 1) { + if (verticalWalls[x + 1] === undefined) { + verticalWalls[x + 1] = []; + } + if (verticalWalls[x + 1].indexOf(y) === -1) { + verticalWalls[x + 1].push(y); + } + } else if (dY === -1) { + if (horizontalWalls[y] === undefined) { + horizontalWalls[y] = []; + } + if (horizontalWalls[y].indexOf(x) === -1) { + horizontalWalls[y].push(x); + } + } else if (dY === 1) { + if (horizontalWalls[y + 1] === undefined) { + horizontalWalls[y + 1] = []; + } + if (horizontalWalls[y + 1].indexOf(x) === -1) { + horizontalWalls[y + 1].push(x); + } + } + } + } + }); + + return { verticalWalls, horizontalWalls }; +} + +function mergeWallSegments(vertical, horizontal) { + const result = []; + const walls = [vertical, horizontal]; + + for (let i = 0; i < 2; i++) { + const wallList = walls[i]; + for (let a in wallList) { + a = parseInt(a, 10); + + wallList[a].sort((a, b) => { + return a - b; + }); + + let startPos = wallList[a][0]; + const isHorizontal = i === 1; + + if (wallList[a].length === 1) { + const startPosX = isHorizontal ? startPos : a; + const startPosY = isHorizontal ? a : startPos; + result.push({ + startPosX, + startPosY, + isHorizontal, + length: 1 + }); + } else { + let consecutiveCount = 1; + for (let b = 0; b < wallList[a].length - 1; b++) { + if (b + 1 === wallList[a].length - 1) { + if (wallList[a][b + 1] - wallList[a][b] > 1) { + const startPosX = isHorizontal ? startPos : a; + const startPosY = isHorizontal ? a : startPos; + result.push({ + startPosX, + startPosY, + isHorizontal, + length: consecutiveCount + }); + consecutiveCount = 0; + startPos = wallList[a][b + 1]; + } + const startPosX = isHorizontal ? startPos : a; + const startPosY = isHorizontal ? a : startPos; + result.push({ + startPosX, + startPosY, + isHorizontal, + length: consecutiveCount + 1 + }); + break; + } else if (wallList[a][b + 1] - wallList[a][b] > 1) { + const startPosX = isHorizontal ? startPos : a; + const startPosY = isHorizontal ? a : startPos; + result.push({ + startPosX, + startPosY, + isHorizontal, + length: consecutiveCount + }); + startPos = wallList[a][b + 1]; + consecutiveCount = 0; + } + consecutiveCount++; + } + } + } + } + + return result; +} + +export function deriveValidNextTilePositions(rooms, selectedTiles) { + const result = [], + newPosition = { x: 0, y: 0 }; + let isSurroundingTile; + + selectedTiles.forEach(tile => { + const x = tile.positionX; + const y = tile.positionY; + result.push({ x, y }); + + for (let dX = -1; dX <= 1; dX++) { + for (let dY = -1; dY <= 1; dY++) { + if (Math.abs(dX) === Math.abs(dY)) { + continue; + } + + newPosition.x = x + dX; + newPosition.y = y + dY; + + isSurroundingTile = true; + for (let index in selectedTiles) { + if ( + selectedTiles[index].positionX === newPosition.x && + selectedTiles[index].positionY === newPosition.y + ) { + isSurroundingTile = false; + break; + } + } + + if ( + isSurroundingTile && + findPositionInRooms(rooms, newPosition.x, newPosition.y) === -1 + ) { + result.push({ x: newPosition.x, y: newPosition.y }); + } + } + } + }); + + return result; +} + +export function findPositionInPositions(positions, positionX, positionY) { + for (let i = 0; i < positions.length; i++) { + const position = positions[i]; + if (positionX === position.x && positionY === position.y) { + return i; + } + } + + return -1; +} + +export function findPositionInRooms(rooms, positionX, positionY) { + for (let i = 0; i < rooms.length; i++) { + const room = rooms[i]; + if (findPositionInTiles(room.tiles, positionX, positionY) !== -1) { + return i; + } + } + + return -1; +} + +function findPositionInTiles(tiles, positionX, positionY) { + let index = -1; + + for (let i = 0; i < tiles.length; i++) { + const tile = tiles[i]; + if (positionX === tile.positionX && positionY === tile.positionY) { + index = i; + break; + } + } + + return index; +} + +export function findTileWithPosition(tiles, positionX, positionY) { + for (let i = 0; i < tiles.length; i++) { + if (tiles[i].positionX === positionX && tiles[i].positionY === positionY) { + return tiles[i]; + } + } + + return null; +} + +export function calculateRoomListBounds(rooms) { + const min = { x: Number.MAX_VALUE, y: Number.MAX_VALUE }; + const max = { x: -1, y: -1 }; + + rooms.forEach(room => { + room.tiles.forEach(tile => { + if (tile.positionX < min.x) { + min.x = tile.positionX; + } + if (tile.positionY < min.y) { + min.y = tile.positionY; + } + + if (tile.positionX > max.x) { + max.x = tile.positionX; + } + if (tile.positionY > max.y) { + max.y = tile.positionY; + } + }); + }); + + max.x++; + max.y++; + + const center = { + x: min.x + (max.x - min.x) / 2.0, + y: min.y + (max.y - min.y) / 2.0 + }; + + return { min, center, max }; +} |
