Solution to level 13 in Untrusted: http://alex.nisnevich.com/untrusted/
/* | |
* robotMaze.js | |
* | |
* The blue key is inside a labyrinth, and extracting | |
* it will not be easy. | |
* | |
* It's a good thing that you're a AI expert, or | |
* we would have to leave empty-handed. | |
*/ | |
function startLevel(map) { | |
// Hint: you can press R or 5 to "rest" and not move the | |
// player, while the robot moves around. | |
map.getRandomInt = function(min, max) { | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
map.placePlayer(map.getWidth()-1, map.getHeight()-1); | |
var player = map.getPlayer(); | |
map.defineObject('robot', { | |
'type': 'dynamic', | |
'symbol': 'R', | |
'color': 'gray', | |
'onCollision': function (player, me) { | |
me.giveItemTo(player, 'blueKey'); | |
}, | |
'behavior': function (me) { | |
if (!('dirs' in me)) { | |
me.dirs = Array(map.getWidth()); | |
for (var i=0; i<map.getWidth(); i++) { | |
me.dirs[i] = Array(map.getHeight()); | |
} | |
var keypos = me.findNearest('blueKey'); | |
var dist=0; | |
var edges = [[keypos.x, keypos.y, '']]; | |
while (edges.length>0) { | |
var next_edges = []; | |
while (edges.length>0) { | |
var edge = edges.shift(); | |
me.dirs[edge[0]][edge[1]] = { | |
'dist': dist, | |
'dir': edge[2] | |
}; | |
var adj_cells = map.getAdjacentEmptyCells( | |
edge[0], edge[1]); | |
while (adj_cells.length>0) { | |
var cell = adj_cells.shift(); | |
var x = cell[0][0]; | |
var y = cell[0][1]; | |
map.setSquareColor(x,y,'#020'); | |
if (map.getObjectTypeAt(x,y) != 'barrier' && | |
!(y in me.dirs[x])) { | |
next_edges.push([x,y,cell[1]]); | |
} | |
} | |
} | |
edges = next_edges; | |
dist++; | |
} | |
} | |
if (me.got_key) | |
me.move('down'); | |
else { | |
var dat = me.dirs[me.getX()][me.getY()]; | |
if (dat.dist == 0) { | |
me.got_key = true; | |
} else switch (dat.dir) { | |
case 'up': | |
me.move('down'); | |
break; | |
case 'down': | |
me.move('up'); | |
break; | |
case 'left': | |
me.move('right'); | |
break; | |
case 'right': | |
me.move('left'); | |
break; | |
} | |
} | |
} | |
}); | |
map.defineObject('barrier', { | |
'symbol': '░', | |
'color': 'purple', | |
'impassable': true, | |
'passableFor': ['robot'] | |
}); | |
map.placeObject(0, map.getHeight() - 1, 'exit'); | |
map.placeObject(1, 1, 'robot'); | |
map.placeObject(map.getWidth() - 2, 8, 'blueKey'); | |
map.placeObject(map.getWidth() - 2, 9, 'barrier'); | |
var autoGeneratedMaze = new ROT.Map.DividedMaze(map.getWidth(), 10); | |
autoGeneratedMaze.create( function (x, y, mapValue) { | |
// don't write maze over robot or barrier | |
if ((x == 1 && y == 1) || (x == map.getWidth() - 2 && y >= 8)) { | |
return 0; | |
} else if (mapValue === 1) { //0 is empty space 1 is wall | |
map.placeObject(x,y, 'block'); | |
} else { | |
map.placeObject(x,y,'empty'); | |
} | |
}); | |
} | |
function validateLevel(map) { | |
map.validateExactlyXManyObjects(1, 'exit'); | |
map.validateExactlyXManyObjects(1, 'robot'); | |
map.validateAtMostXObjects(1, 'blueKey'); | |
} | |
function onExit(map) { | |
if (!map.getPlayer().hasItem('blueKey')) { | |
map.writeStatus("We need to get that key!"); | |
return false; | |
} else { | |
return true; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment