Skip to content

Instantly share code, notes, and snippets.

@Larkenx
Last active December 5, 2020 11:11
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Larkenx/b5dfb53a8ca041d79e5462617f41453e to your computer and use it in GitHub Desktop.
Save Larkenx/b5dfb53a8ca041d79e5462617f41453e to your computer and use it in GitHub Desktop.
const key = (x, y) => {
return x + ',' + y
}
const unkey = k => {
return k.split(',').map(s => parseInt(s))
}
/* Given an x, y coordinate and a hashmap "x,y" => boolean values that indicate whether or not the tile at that
coordinate is blocked, this function will calculate the bitmask sum of the given coordinate. */
function computeBitmask(x, y, blockedCells) {
let sum = 0
let above = `${x},${y - 1}`
let below = `${x},${y + 1}`
let left = `${x - 1},${y}`
let right = `${x + 1},${y}`
let ur = `${x + 1},${y - 1}`
let ll = `${x - 1},${y + 1}`
let ul = `${x - 1},${y - 1}`
let lr = `${x + 1},${y + 1}`
let blocked = coord => {
return !(coord in blockedCells) || blockedCells[coord]
}
if (blocked(above)) sum += 2
if (blocked(right)) sum += 16
if (blocked(below)) sum += 64
if (blocked(left)) sum += 8
if (blocked(ul) && blocked(above) && blocked(left)) sum += 1
if (blocked(ur) && blocked(above) && blocked(right)) sum += 4
if (blocked(ll) && blocked(below) && blocked(left)) sum += 32
if (blocked(lr) && blocked(below) && blocked(right)) sum += 128
return sum
}
/* A map of bitmask sums to a corresponding index of a unicode character */
const sumToTileIdMap = {
2: 1, 8: 2, 10: 3, 11: 4, 16: 5, 18: 6, 22: 7, 24: 8, 26: 9, 27: 10, 30: 11, 31: 12,
64: 13, 66: 14, 72: 15, 74: 16, 75: 17, 80: 18, 82: 19, 86: 20, 88: 21, 90: 22, 91:
23, 94: 24, 95: 25, 104: 26, 106: 27, 107: 28, 120: 29, 122: 30, 123: 31, 126: 32,
127: 33, 208: 34, 210: 35, 214: 36, 216: 37, 218: 38, 219: 39, 222: 40, 223: 41,
246: 36, 248: 42, 250: 43, 251: 44, 254: 45, 255: 46, 0: 47
}
/* This pre-computed matrix of unicode box tiles corresponds to this resource's corner tiles
https://gamedevelopment.tutsplus.com/tutorials/how-to-use-tile-bitmasking-to-auto-tile-your-level-layouts--cms-25673
*/
const unicodeBoxTiles = [
['╦', '║', '═', '╝', '╝', '═', '╚', '╚'],
['═', '╩', '╩', '╩', '═', '║', '║', '╗'],
['╣', '╣', '╔', '╠', '╠', '╦', '╬', '╦'],
['═', '╦', '╗', '╣', '║', '╦', '╠', '╠'],
['╬', '╔', '╔', '╠', '║', '╦', '╬', '╬'],
['╣', '╗', '═', '╩', '╚', '╝', '', '╬']
]
const flattenedUnixBoxTiles = [
'╦', '║', '═', '╝', '╝', '═', '╚', '╚',
'═', '╩', '╩', '╩', '═', '║', '║', '╗',
'╣', '╣', '╔', '╠', '╠', '╦', '╬', '╦',
'═', '╦', '╗', '╣', '║', '╦', '╠', '╠',
'╬', '╔', '╔', '╠', '║', '╦', '╬', '╬',
'╣', '╗', '═', '╩', '╚', '╝', '', '╬'
]
function getCharacter(sum) {
return !(sumToTileIdMap[sum] in flattenedUnixBoxTiles) ? '!' : flattenedUnixBoxTiles[sumToTileIdMap[sum]]
}
/* Example of a simple room
#### ╔══╗
# # ║ ║
#### ╚══╝
*/
/* Generate a boolean matrix of blocked and not blocked tiles */
let T = true
let F = false
let map = [
[T, T, T, T, T],
[T, F, F, F, T],
[T, F, F, F, T],
[T, T, T, T, T]
]
/* Create hashmap of blocked cells (this is a standard format for generating maps with rot-js) */
let blockedCells = {}
for (let y = 0; y < map.length; y++) {
for (let x = 0; x < map[0].length; x++) {
blockedCells[key(x, y)] = map[y][x]
}
}
/* For each tile in 2D Matrix, find the corresponding unicode box character associated with it by calculating the bit mask sum
if it's wall */
let result = ''
for (let y = 0; y < map.length; y++) {
for (let x = 0; x < map[0].length; x++) {
if (map[y][x]) {
let sum = computeBitmask(x, y, blockedCells)
result += getCharacter(sum)
} else {
result += '.'
}
}
result += '\n'
}
console.log(result)
/* Output:
╔═══╗
║...║
║...║
╚═══╝
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment