How do I solve Untrusted's levels?



  • I am playing https://alexnisnevich.github.io/untrusted/ (JavaScript adventure game) and I am stuck at a particular level. How do I solve that?

    Even after I solved a level, I am curious to know if there are better approaches. Is there a compilation, or a walk-through of optimal ways to solve Untrusted's levels?



  • As all the successful solutions are https://gist.github.com/Untrusted-Game , I spend some time analyzing them and compiled a list of all the (sensible) approaches to solve each level, that I could find.

    https://gist.github.com/mhasdf/40363e0c1c807663d8c6ccb797aa94fa


    Solutions for the Untrusted Game

    untrusted game: https://alexnisnevich.github.io/untrusted/

    Level 1

    cellBlockA.js
    01_cellBlockA.jsx

    // remove all code
    

    Level 2

    theLongWayOut.js
    02_theLongWayOut.jsx

    /*
    */
    

    Level 3

    validationEngaged.js
    03_validationEngaged.jsx

        for (y = 10; y for (x = 5; x <= map.getWidth() - 5; x++) {
        map.placeObject(x, 10, 'block');
        map.placeObject(x, map.getHeight() - 3, 'block');
    }
    

    Level 4

    multiplicity.js
    04_multiplicity.jsx

    map.placeObject(40, 20, 'exit');
    

    Level 5

    minesweeper.js
    05_minesweeper.jsx

    map.setSquareColor(x, y, '#000');
    

    Level 6

    drones101.js
    06_drones101.jsx

    map.placeObject(20, 11, 'block');
    map.placeObject(20, 12, 'block');
    map.placeObject(21, 13, 'block');
    map.placeObject(22, 12, 'block');
    

    or

    var i = 0;
    map.defineObject('timebomb', {
        'type': 'dynamic',
        'symbol': 'C',
        'color': '#ff0',
        'behavior': function (me) {
            if (i === 10) {
                x = 37;
                y = 12;
                map.placeObject(x-1, y, 'block');
                map.placeObject(x+1, y, 'block');
                map.placeObject(x, y-1, 'block');
                map.placeObject(x, y+1, 'block');
            }
            i++;
        }
    });
    map.placeObject(34, 12, 'timebomb');
    

    or with an idea from a later level

    map.placeObject(1, 13, 'teleporter');
    map.placeObject(45, 13, 'teleporter');
    var t = map.getDynamicObjects();
    t[1].setTarget(t[2]);
    

    or with an idea from a later level

    map.defineObject('turret', {
        'type': 'dynamic',
        'symbol': '=',
        'color': 'yellow',
        'interval': 200,
        'behavior': function (me) {
            if ((me.i = (me.i ?? 0) + 1) < 10) {
                map.placeObject(me.getX() + 1, me.getY(), 'bullet');
            }
        }
    });
    map.defineObject('bullet', {
        'type': 'dynamic',
        'symbol': '.',
        'color': 'yellow',
        'interval': 100,
        'projectile': true,
        'behavior': function (me) {
            me.move('right');
        }
    });
    map.placeObject(20, 12, 'turret');
    

    https://gist.github.com/search?q=%22untrusted-lvl6-solution.js%22

    Level 7

    colors.js
    07_colors.jsx

    var player = map.getPlayer();
    var colors = {
        '#f00': '#ff0',
        '#ff0': '#0f0',
        '#0f0': '#f00'
    };
    player.setColor(colors[player.getColor()]);
    

    or

    var player = map.getPlayer();
    if (player.i === undefined) player.i = 0;
    var colors = ['#f00', '#ff0', '#0f0'];
    player.setColor(colors[player.i]);
    player.i = (player.i + 1) % colors.length;
    

    or

    var player = map.getPlayer();
    var colors = ['#0f0', '#f00', '#ff0'];
    var i = player.i ?? 0;
    map.startTimer(function () {
      player.setColor(colors[i++ % colors.length]);
    }, 500);
    

    or

    var player = map.getPlayer();
    if (player.getX() === 24 || player.getX() === 33) {
        player.setColor('#f00');
    } else if (player.getX() === 27 || player.getX() === 36) {
        player.setColor('#ff0');
    } else {
        player.setColor('#0f0');
    }
    

    Nice to remember:

    map.getPlayer().setPhoneCallback(function () {});
    

    https://gist.github.com/search?q=%22untrusted-lvl7-solution.js%22

    Level 8

    intoTheWoods.js
    08_intoTheWoods.jsx

    "generateForest"
    

    Level 9

    fordingTheRiver.js
    09_fordingTheRiver.jsx

    map.defineObject('bridge', {
        'type': 'dynamic',
        'symbol': '☰',
        'color': '#f77',
        'transport': true,
    });
    for (var y = 5; y < 15; y++) {
        map.placeObject(10, y, 'bridge');
    }
    

    or

    map.getPlayer().setPhoneCallback(function () {
        raftDirection = 'up';
    });
    

    https://gist.github.com/search?q=%22untrusted-lvl9-solution.js%22

    Level 10

    ambush.js
    10_ambush.jsx

    ///// attackDrone
    if (me.canMove('up')) {
        me.move('up');
    } else {
        me.move('left');
    }
    ///// reinforcementDrone
    me.move('up');
    ///// defenseDrone
    if (me.canMove('up')) {
        me.move('up');
    } else {
        me.move('right');
    }
    

    https://gist.github.com/search?q=%22untrusted-lvl10-solution.js%22

    Level 11

    robot.js
    11_robot.jsx

    if (me.canMove('right')) {
        me.move('right');
    } else {
        me.move('down');
    }
    

    https://gist.github.com/search?q=%22untrusted-lvl11-solution.js%22

    Level 12

    robotNav.js
    12_robotNav.jsx

    if (me.getX() < 25) {
        if (me.canMove('down')) {
            me.move('down');
        } else {
            me.move('right');
        }
    } else if (me.getX() < 30) {
        if (me.canMove('up')) {
            me.move('up');
        } else {
            me.move('right');
        }
    } else {
        if (me.canMove('right')) {
            me.move('right');
        } else {
            me.move('down');
        }
    }
    

    Also, see Level 13 solutions.

    https://gist.github.com/search?q=%22untrusted-lvl12-solution.js%22

    Level 13

    robotMaze.js
    13_robotMaze.jsx

    var a = ['left', 'up', 'right', 'down'];
    if (me.i === undefined) {
        me.i = 0;
        map.getPlayer().setPhoneCallback(function () {
            me.i = (me.i + 1) % 4;
        });
    }
    me.move(a[me.i]);
    

    or

    map.setSquareColor(41, 22, '#770');
    map.setSquareColor(42, 21, '#770');
    map.setSquareColor(43, 22, '#770');
    map.setSquareColor(42, 23, '#770');
    if (player.atLocation(41, 22))
        me.move('left');
    if (player.atLocation(42, 21))
        me.move('up');
    if (player.atLocation(43, 22))
        me.move('right');
    if (player.atLocation(42, 23))
        me.move('down');
    

    or

    if (me.i === undefined) {
        me.i = 1;
        map.getPlayer().setPhoneCallback(function () {
            if (me.i++ % 2) {
                map.overrideKey('left', ()=>{ me.move('left'); });
                map.overrideKey('up', ()=>{ me.move('up'); });
                map.overrideKey('right', ()=>{ me.move('right'); });
                map.overrideKey('down', ()=>{ me.move('down'); });
            } else {
                map.overrideKey('left', null);
                map.overrideKey('up', null);
                map.overrideKey('right', null);
                map.overrideKey('down', null);
            }
        });
    }
    

    or

    var a = {
        'left': ['down', 'up'],
        'up': ['left', 'right'],
        'right': ['up', 'down'],
        'down': ['right', 'left'],
    };
    if (me.i === undefined) me.i = 'up';
    if (me.j === undefined) me.j = false;
    if (me.j && me.canMove(a[me.i][0])) {
        me.i = a[me.i][0];
    } else if (me.canMove(me.i) && !me.canMove(a[me.i][0])) {
        me.j = true;
    } else if (!me.canMove(me.i)) {
        me.i = a[me.i][1];
    }
    me.move(me.i);
    

    https://gist.github.com/search?q=%22untrusted-lvl13-solution.js%22

    Level 14

    crispsContest.js
    14_crispsContest.jsx

    theAlgorithm
    

    left (blue), greenKey, up, blueKey, center, right (red), blueKey, up, redKey, center, down, theAlgorithm, right, yellowKey, center, exit

    https://gist.github.com/search?q=%22untrusted-lvl14-solution.js%22

    Level 15

    exceptionalCrossing.js
    15_exceptionalCrossing.jsx

    a
    

    or

    '');}, 'onCollision':function () {//
    

    Level 16

    lasers.js
    16_lasers.jsx

    // using canvas to draw the line
    var ctx = map.getCanvasContext();
    ctx.beginPath();
    ctx.strokeStyle = color;
    ctx.lineWidth = 5;
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    /////
    map.getPlayer().setPhoneCallback(function () {
        var player = map.getPlayer();
        player.i = ((player.i ?? -1) + 1) % colors.length;
        player.setColor(colors[player.i]);
    });
    

    https://gist.github.com/search?q=%22untrusted-lvl16-solution.js%22

    Level 17

    pointers.js
    17_pointers.jsx

    if (i === teleportersAndTraps.length - 2) {
        var obj = map.getDynamicObjects();
        var a = obj[0];
        var b = obj[obj.length - 2];  // teleporter nearest to exit
        a.setTarget(b);
        var c = map.getCanvasContext();
        c.beginPath();
        c.strokeStyle = 'purple';
        c.lineWidth = 4;
        c.moveTo(map.getCanvasCoords(a).x, map.getCanvasCoords(a).y);
        c.lineTo(map.getCanvasCoords(b).x, map.getCanvasCoords(b).y);
        c.stroke();
    }
    

    https://gist.github.com/search?q=%22untrusted-lvl17-solution.js%22

    Level 18

    superDrEvalBros.js
    18_superDrEvalBros.jsx

    }
    function gravity() {
    

    or

    map.defineObject('bridge', {
        'symbol': '=',
        'color': '#dd0',
        'impassable': true
    });
    for (var x = 20; x < 30; x++) {
        map.placeObject(x, fl(h/2), 'bridge');
    }
    

    or

    map.placeObject(19,11,'teleporter');
    map.placeObject(30,11,'teleporter');
    var d = map.getDynamicObjects();
    d[0].setTarget(d[1]);
    

    or

    map.startTimer(function () {
        var x = player.getX();
        var y = player.getY();
        if (x < 35) {
            if (y > 1) {
                player.move('up');
            } else {
                player.move('right');
            }
        }
    }, 25);
    

    https://gist.github.com/search?q=%22untrusted-lvl18-solution.js%22

    Level 19

    documentObjectMadness.js
    19_documentObjectMadness.jsx

    Bring the green highlight (deEval) to the red highlight (adversary)

    • up = moveToParent
    • down = moveToFirstChild
    • left = moveToPreviousSibling
    • right = moveToNextSibling

    Level 20

    bossFight.js
    20_bossFight.jsx

    map.defineObject('missile', {
        'type': 'dynamic',
        'symbol': '^',
        'color': 'orange',
        'projectile': true,
        'interval': 100,
        'behavior': function (me) {
            me.move('up');
        }
    });
    /// You need to make it to the other side for the phone :-(
    var player = map.getPlayer()
    player.setPhoneCallback(() => {
        map.placeObject(player.getX(), player.getY() -2, 'missile');
    });
    

    or

    map.defineObject('missile', {
        'type': 'dynamic',
        'symbol': '^',
        'color': 'orange',
        'projectile': true,
        'interval': 100,
        'behavior': function (me) {
            me.move('up');
        }
    });
    /// Shield
    map.defineObject('shield', {
        'type': 'dynamic',
        'symbol': '/',
        'color': 'purple',
        'impassable': true,
        'passableFor': ['missile']
    });
    for(var x = 2; x < 48; x++) {
        map.placeObject(x, 19, 'shield');
    }
    var player = map.getPlayer();
    player.setPhoneCallback(() => {
        map.placeObject(player.getX(), player.getY() -2, 'missile');
    });
    

    or

    map.defineObject('missile', {
        'type': 'dynamic',
        'symbol': '^',
        'color': 'orange',
        'projectile': true,
        'interval': 100,
        'behavior': function (me) {
            me.move('up');
        }
    });
    /// Don't let the boss fire
    Math.random = function () {
        return 1;
    }
    var player = map.getPlayer();
    player.setPhoneCallback(() => {
        map.placeObject(player.getX(), player.getY() -2, 'missile');
    });
    

    or

    map.defineObject('missile', {
        'type': 'dynamic',
        'symbol': '^',
        'color': 'orange',
        'projectile': true,
        'interval': 100,
        'behavior': function (me) {
            me.move('up');
        }
    });
    /// Use left arrow key
    map.overrideKey('left', function () {
        for (var x = 0; x < map.getWidth(); x++) {
            map.placeObject(x, 15, 'missile');
        }
    });
    

    or

    map.defineObject('missle', {
        'type': 'dynamic',
        'symbol': '>',
        'color': 'orange',
        'projectile': true,
        'interval': 100,
        'behavior': function (me) {
            me.move('right');
        }
    });
    map.defineObject('trigger', {
        'symbol': '+',
        'color': 'orange',
        'onCollision': function () {
            map.placeObject(0,5, 'missle');
            map.placeObject(0,6, 'missle');
        }
    });
    map.placeObject(0, 24, 'trigger');
    

    or

    map.defineObject('missle', {
        'type': 'dynamic',
        'symbol': '>',
        'color': 'orange',
        'projectile': true,
        'interval': 100,
        'behavior': function (me) {
            me.move('right');
        }
    });
    Math.random = function () {
        map.placeObject(0, 5, 'missle');
        map.placeObject(0, 6, 'missle');
        return 1;
    }
    

    or

    map.defineObject('trigger', {
        'symbol': '+',
        'color': 'orange',
        'onCollision': function () {
            map.getDynamicObjects().forEach( function (o) {
                /// Hit them with their own bullets
                map.placeObject(o.getX(), o.getY() - 1, 'bullet');
            });
        }
    });
    map.placeObject(0, 24, 'trigger');
    

    or

    /// Landing
    map.getDynamicObjects().forEach(function (o) {
        o.direction = "down";
    });
    map.getPlayer().setPhoneCallback(function () {
        for(var x = 2; x < 48; x++) {
            map.placeObject(x, 10, 'bullet');
        }
    });
    

    https://gist.github.com/search?q=%22untrusted-lvl20-solution.js%22

    Level 21

    21_endOfTheLine.jsx

    Go to Menu, scripts/objects.js

    Find this code and comment out the if condition

    'exit' : {
        'symbol' : String.fromCharCode(0x2395), // ⎕
        'color': '#0ff',
        'onCollision': function (player) {
            if (!game.map.finalLevel) {
                game._callUnexposedMethod(function () {
                    game._moveToNextLevel();
                });
            }
        }
    },
    

    bonus / 01_inTheDesert.jsx

    inTheDesert.js

    No code changes needed. Don't move too far away from the E. The E deactivates the laser.

    bonus / 02_theEmptyRoom.jsx

    theEmptyRoom.js

    return {15:610,
    16:987,
    17:1597,
    18:2584,
    19:4181,
    20:6765,
    21:10946,
    22:17711,
    23:28657,
    24:46368,
    25:75025,
    26:121393,
    27:196418,
    28:317811,
    29:514229,
    30:832040,
    31:1346269,
    32:2178309,
    33:3524578,
    34:5702887,
    35:9227465,
    36:14930352,
    37:24157817,
    38:39088169,
    39:63245986,
    40:102334155,
    41:165580141,
    42:267914296,
    43:433494437,
    44:701408733,
    45:1134903170,
    46:1836311903,
    47:2971215073,
    48:4807526976,
    49:7778742049,
    50:12586269025,
    51:20365011074,
    52:32951280099,
    53:53316291173,
    54:86267571272,
    55:139583862445,
    56:225851433717,
    57:365435296162,
    58:591286729879,
    59:956722026041,
    60:1548008755920,
    61:2504730781961,
    62:4052739537881,
    63:6557470319842,
    64:0x9a661ca20bb,
    65:0xf9d297a859d,
    66:27777890035288,
    67:44945570212853,
    68:72723460248141,
    69:0x6b04f4c2fe42,
    70:0xad2934c6d08f,
    71:308061521170129,
    72:498454011879264,
    73:806515533049393,
    74:0x4a2dce62b0d91,
    75:0x780626e057bc2,
    76:0xc233f54308953,
    77:5527939700884757,
    78:8944394323791464,
    79:0x336a82d89c937c,
    80:0x533163ef0321e4,
    81:0x869be6c79fb560,
    82:0xd9cd4ab6a2d740,
    83:99194853094755490,
    84:0x23a367c34e563e0,
    85:0x39a9fadb327f080,
    86:0x5d4d629e80d5480,
    87:0x96f75d79b354500,
    88:0xf444c0183429980,
    89:0x18b3c1d91e77de00,
    90:0x27f80ddaa1ba7800,
    91:466004661037553e4,
    92:0x68a3dd8e61ecd000,
    93:0xa94fad42221f2800,
    94:0x111f38ad0840c0000,
    95:319404346349901e5,
    96:5168070885485833e4,
    97:8362114348984843e4,
    98:0x755b0bdd8fa998000,
    99:2189229958345552e5,
    100:3542248481792619e5}[input];
    

    bonus / 03_theCollapsingRoom.jsx

    theCollapsingRoom.js

    half_width = 5;
    

    bonus / 04_theGuard.jsx

    theGuard.js

    map.placeObject(26, 12, 'block');
    map.placeObject(28, 12, 'block');
    map.placeObject(27, 13, 'block');
    

    or

    /// Use eyes to block guard
    map.placeObject(40, 20, 'eye');
    

    bonus / 05_theCorridor.jsx

    function trap_behaviour (me, left, right) {}
    

    bonus / AB_1_ANewJourney.jsx

    ANewJourney.js

    /// Modify map - does not work in other levels
    for (var x = 0; x < map.getWidth(); x++) {
        for (var y = 0; y < map.getHeight(); y++) {
            if (map.getObjectTypeAt(x, y) === 'tree') {
                map.placeObject(x, y, 'empty');
            }
        }
    }
    

    or

    function getRandomInt() { return 4; }
    map.placeObject(42, 8, 'empty');
    

    or

    map.placeObject(map.getWidth()-8, 1, 'empty');
    map.placeObject(map.getWidth()-18, 1, 'empty');
    map.placeObject(map.getWidth()-13, 2, 'empty');
    map.placeObject(map.getWidth()-8, 4, 'empty');
    map.placeObject(map.getWidth()-8, 7, 'empty');
    map.placeObject(map.getWidth()-16, 6, 'empty');
    map.placeObject(10, 20, 'exit');
    

    bonus / AB_2_FrozenCave.jsx

    FrozenCave.js

    /// Modify map - does not work in other levels
    for (var i=2; i

    bonus / AB_3_BoulderMadness.jsx

    BoulderMadness.js

    color: 'white',
    /////
    color: 'yellow',
    /////
    color: 'red',
    

    bonus / AB_4_BatAttack.jsx

    BatAttack.js

    map.placeObject(6, 23, 'teleporter');
    map.placeObject(39, 1, 'teleporter');
    var objs = map.getDynamicObjects();
    var ts = [];
    for (i = 0; i < objs.length; i++) {
        var t = objs[i];
        if (t.getType() == 'teleporter') {
            ts.push(t);
        }
    }
    ts[0].setTarget(ts[1]);
    

    or

    function wakeAndHunt(obj, type) {}
    

    bonus / AB_5_PathOfDoom.jsx

    PathOfDooM.js

    map.placeObject(45, 12, 'block');
    

    bonus / darkAlley.jsx

    darkAlley.jsx

    map.placeObject(30, 17, 'goldengun');
    

    bonus / ice.jsx

    ice.js

    map.startTimer(function () {
         map.getPlayer().move('up');
    }, 25);
    

    bonus / labryinth.jsx

    if (me.getX() > 43) {
        me.move('up');
    }
    /////
    map.placeObject(1, 10, 'boulder');
    for (x = 29; x < 39; x++) {
        map.placeObject(x, 14, 'block');
    }
    for (var x = 0; x < map.getWidth(); x++) {
        for (var y = 0; y < map.getHeight(); y++) {
            map.setSquareColor(x, y, '#444')
        }
    }
    

    bonus / levelName.jsx

    .js

    map.defineObject('helper', {
        'symbol': '%',
        'color': '#0f0',
        'impassable': function (player) {
            if (player.getColor() == this.color) {
                return false;
            }
            player.setColor('#0f0');
            return true;
        }
    });
    map.placeObject(30, 9, 'helper');
    

    or

    map.overrideKey('down', function () {
        var player = map.getPlayer();
        player.setColor('#0f0');
        player.move('down');
    });
    

    bonus / noWayOut.jsx

    102_noWayOut.js

    buildWall = function () {};
    

    bonus / pushme.jsx

    pushme.js

    });function moveToward(obj,type){obj.move('down')}var a =({
    

    or

    /// Move the blocks wisely
    pushable: true,
    

    bonus / soccer.jsx

    soccer.jsx

    function moveGoalie(goalie) { goalie.move('down'); }
    kickedDirection = 'right';
    

    or

    moveGoalie = function () {}
    moveEnemyPlayer = function () {}
    

    bonus / threeKeys.jsx

    ???

    bonus / trapped.jsx

    trapped.js

    moveToward = function () {}
    

    Don't push a box against another object.

    bonus / wallsWithEyes.jsx

    wallsWithEyes

    teleport2.setTarget(teleport1);
    

    Non-Documented API

    • map.writeStatus('message');
    • object.impassable: true, passableFor: ['missile']
    • object.impassableFor: ['raft']
    • object.transport: true // prevents from collision with object at same position
    • object.pushable: true
    • object.type: 'block', 'tree', 'teleporter', 'empty'
    • object.type: 'mine', 'trap' // deadly
    • object.type: 'exit', 'player'
    • object.type: 'computer', 'phone', 'redKey', 'greenKey', 'blueKey', 'yellowKey', 'theAlgorithm'
    • object.type: 'eye', 'guard'
    • object.type: 'item', onPickUp: f(), onDrop: f()
    • object.interval: 200, behavior: f()

Log in to reply
 

Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2