Skip to content

Instantly share code, notes, and snippets.

@j-quelly
Last active January 1, 2019 01:16
Show Gist options
  • Save j-quelly/608484f7bab1881320a9fa6cf72dd5de to your computer and use it in GitHub Desktop.
Save j-quelly/608484f7bab1881320a9fa6cf72dd5de to your computer and use it in GitHub Desktop.
// 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