Last active
January 1, 2019 01:16
-
-
Save j-quelly/608484f7bab1881320a9fa6cf72dd5de to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// passing 100% of tests | |
function getStartPosition(m) { | |
let position = ''; | |
m.forEach((row, x) => { | |
const cells = row.split(''); | |
const y = cells.indexOf('*'); | |
if (y !== -1) { | |
position += x + ','; | |
position += y; | |
} | |
}); | |
return position; | |
} | |
const getOutOfBoundsTile = ({ x, y, move, m }) => { | |
let pos; | |
// moving up | |
if (move[0] === -1 && move[1] === 0) { | |
pos = `${m.length - 1},${y + move[1]}`; | |
} | |
// moving right | |
if (move[0] === 0 && move[1] === 1) { | |
pos = `${x + move[0]},${0}`; | |
} | |
// moving down | |
if (move[0] === 1 && move[1] === 0) { | |
pos = `${0},${y + move[1]}`; | |
} | |
// moving left | |
if (move[0] === 0 && move[1] === -1) { | |
pos = `${x + move[0]},${m[x].length - 1}`; | |
} | |
return pos; | |
}; | |
const removeItemFromMap = ({m, board, pos}) => { | |
return m.map((row) => { | |
if (row.indexOf(board.history[pos].tile) >= 0) { | |
return row.replace(board.history[pos].tile, ' '); | |
} | |
return row; | |
}); | |
}; | |
function explore(m, board, character) { | |
if (character.foundExit) { | |
return; | |
} | |
const validTile = /[\s|a-z|*]/; | |
const currentPos = character.currentPosition.split(','); | |
const x = currentPos[0]; | |
const y = currentPos[1]; | |
// visit all other possible tiles | |
const adjacentTiles = [[-1, 0], [0, 1], [1, 0], [0, -1]]; | |
adjacentTiles.forEach((move) => { | |
let pos = `${+x + move[0]},${+y + move[1]}`; | |
if (!board.history[pos]) { | |
pos = getOutOfBoundsTile({ x: +x, y: +y, m, move }); | |
} | |
// if encountering a valid tile | |
if (board.history[pos] && validTile.test(board.history[pos].tile) && board.history[pos].visited === 0) { | |
// if encountering a key | |
if (board.history[pos] && /[a-z]/.test(board.history[pos].tile)) { | |
// remove the key | |
m = removeItemFromMap({ m, board, pos }); | |
// store the key | |
character.keys.push(board.history[pos].tile.toUpperCase()); | |
// reset the board | |
board = new Board(m, {}); | |
} | |
// visit the tile and start a new node | |
board.history[pos].visited += 1; | |
character.currentPosition = pos; | |
return explore(m, new Board(m, board.history), character); | |
} | |
// if encountering a door | |
if (board.history[pos] && /[A-Z]/.test(board.history[pos].tile)) { | |
// check for key | |
if (character.keys.indexOf(board.history[pos].tile) >= 0) { | |
board.history[pos].visited += 1; | |
character.currentPosition = pos; | |
m = removeItemFromMap({ m, board, pos }); | |
return explore(m, new Board(m, board.history), character); | |
} | |
} | |
// if encountering the exit | |
if (board.history[pos] && board.history[pos].tile === '^') { | |
character.foundExit = true; | |
return; | |
} | |
}); | |
} | |
function Board(m, history) { | |
this.history = history; | |
m.forEach((row, x) => { | |
row.split('').forEach((cell, y) => { | |
const key = `${x},${y}`; | |
this.history[key] = { | |
tile: cell, | |
visited: history[key] && history[key].visited === 1 ? 1 : 0, | |
}; | |
}); | |
}); | |
} | |
function dungeonBlaster(m) { | |
const character = { | |
currentPosition: getStartPosition(m), | |
foundExit: false, | |
keys: [], | |
}; | |
// make the first move... | |
explore(m, new Board(m, {}), character); | |
if (character.foundExit) { | |
return true; | |
} | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment