Here are my solutions for Untrusted javascript game chapters 6 through 10. The Untrusted game can be found on github here: http://alexnisnevich.github.io/untrusted/

My solutions are colored red, indicated an area where you can edit the code.

 

Chapter 6 – drones101

So I noticed that the drones movement is determined by some function called “moveToward()”
I redefined the function to just always move left, so that the drone gets out of the way.

 

/****************
* drones101.js *
****************
*
* Do you remember, my dear Professor, a certain introductory
* computational rationality class you taught long ago? Assignment
* #2, behavior functions of autonomous agents? I remember that one
* fondly – but attack drones are so much easier to reason about
* when they’re not staring you in the face, I would imagine!
*/

function startLevel(map) {
function moveToward(obj, type) {
var target = obj.findNearest(type);
var leftDist = obj.getX() – target.x;
var upDist = obj.getY() – target.y;

var direction;
if (upDist == 0 && leftDist == 0) {
return;
} if (upDist > 0 && upDist >= leftDist) {
direction = ‘up’;
} else if (upDist < 0 && upDist < leftDist) {
direction = ‘down’;
} else if (leftDist > 0 && leftDist >= upDist) {
direction = ‘left’;
} else {
direction = ‘right’;
}

if (obj.canMove(direction)) {
obj.move(direction);
}
}

map.defineObject(‘attackDrone’, {
‘type’: ‘dynamic’,
‘symbol’: ‘d’,
‘color’: ‘red’,
‘onCollision’: function (player) {
player.killedBy(‘an attack drone’);
},
‘behavior’: function (me) {
moveToward(me, ‘player’);
}
});

map.placePlayer(1, 1);
map.placeObject(map.getWidth()-2, 12, ‘attackDrone’);
map.placeObject(map.getWidth()-1, 12, ‘exit’);

map.placeObject(map.getWidth()-1, 11, ‘block’);
map.placeObject(map.getWidth()-2, 11, ‘block’);
map.placeObject(map.getWidth()-1, 13, ‘block’);
map.placeObject(map.getWidth()-2, 13, ‘block’);
function moveToward(obj){obj.move(‘left’);};
}

function validateLevel(map) {
map.validateExactlyXManyObjects(1, ‘exit’);
}

Chapter 7 – colors

For this one, I would have liked to check the color of the lock, and then change the color of the player to it. However, I couldn’t figure out how to “get” objects on the map. I tried like… var gL = map.greenLock; but it didn’t seem to work. In lieu of that, since the locks change between three colors I made the function cycle through the colors.

/*************
* colors.js *
*************
*
* You’re almost at the exit. You just need to get past this
* color lock.
*
* Changing your environment is no longer enough. You must
* learn to change yourself. I’ve sent you a little something
* that should help with that.
*/

function startLevel(map) {
map.placePlayer(0, 12);

map.placeObject(5, 12, ‘phone’);

// The function phone lets you call arbitrary functions,
// as defined by player.setPhoneCallback() below.
// The function phone callback is bound to Q or Ctrl-6.
map.getPlayer().setPhoneCallback(function () {
var player = map.getPlayer();
//green to red to yellow to green
if (player.getColor() == “#0f0”){
player.setColor(“#f00”);
} else if (player.getColor() == “#f00”){
player.setColor(“#ff0”);
} else {
player.setColor(“#0f0”);
};

});

map.defineObject(‘redLock’, {
symbol: ‘☒’,
color: “#f00”, // red
impassable: function(player, object) {
return player.getColor() != object.color;
}
});

map.defineObject(‘greenLock’, {
symbol: ‘☒’,
color: “#0f0”, // green
impassable: function(player, object) {
return player.getColor() != object.color;
}
});

map.defineObject(‘yellowLock’, {
symbol: ‘☒’,
color: “#ff0”, // yellow
impassable: function(player, object) {
return player.getColor() != object.color;
}
});

for (var x = 20; x <= 40; x++) {
map.placeObject(x, 11, ‘block’);
map.placeObject(x, 13, ‘block’);
}
map.placeObject(22, 12, ‘greenLock’);
map.placeObject(25, 12, ‘redLock’);
map.placeObject(28, 12, ‘yellowLock’);
map.placeObject(31, 12, ‘greenLock’);
map.placeObject(34, 12, ‘redLock’);
map.placeObject(37, 12, ‘yellowLock’);
map.placeObject(40, 12, ‘exit’);
for (var y = 0; y < map.getHeight(); y++) {
if (y != 12) {
map.placeObject(40, y, ‘block’);
}
for (var x = 41; x < map.getWidth(); x++) {
map.setSquareColor(x, y, ‘#080’);
}
}
}

function validateLevel(map) {
map.validateExactlyXManyObjects(1, ‘exit’);
}

function onExit(map) {
if (!map.getPlayer().hasItem(‘phone’)) {
map.writeStatus(“We need the phone!”);
return false;
} else {
return true;
}
}

Chapter 8 – intoTheWoods

 

I made the phone function call “generateForest”. This redoes the forest each time you phone… so just made my way over while changing the layout of the forest. Pretty simple.

/*******************
* intoTheWoods.js *
*******************
*
* Ah, you’re out of the woods now. Or into the woods, as the
* case may be.
*
* So take a deep breath, relax, and remember what you’re here
* for in the first place.
*
* I’ve traced its signal and the Algorithm is nearby. You’ll
* need to go through the forest and across the river, and
* you’ll reach the fortress where it’s kept. Their defences
* are light, and we should be able to catch them off-guard.
*/

function startLevel(map) {
// NOTE: In this level alone, map.placeObject is allowed to
//overwrite existing objects.

map.displayChapter(‘Chapter 2\nRaiders of the Lost Algorithm’);

map.placePlayer(2, map.getHeight() – 1);

var functionList = {};

functionList[‘fortresses’] = function () {
function genRandomValue(direction) {
if (direction === “height”) {
return Math.floor(Math.random() * (map.getHeight()-3));
} else if (direction === “width”) {
return Math.floor(Math.random() * (map.getWidth()+1));
}
}

var x = genRandomValue(“width”);
var y = genRandomValue(“height”);

for (var i = x-2; i < x+2; i++) {
map.placeObject(i,y-2, ‘block’);
}
for (var i = x-2; i < x+2; i++) {
map.placeObject(i,y+2, ‘block’);
}

for (var j = y-2; j < y+2; j++) {
map.placeObject(x-2,j, ‘block’);
}

for (var j = y-2; j < y+2; j++) {
map.placeObject(x+2,j, ‘block’);
}
};

functionList[‘generateForest’] = function () {
for (var i = 0; i < map.getWidth(); i++) {
for (var j = 0; j < map.getHeight(); j++) {

// initialize to empty if the square contains a forest already
if (map.getObjectTypeAt(i, j) === ‘tree’) {
// remove existing forest
map.placeObject(i,j, ’empty’);
}

if (map.getPlayer().atLocation(i,j) ||
map.getObjectTypeAt(i, j) === ‘block’ ||
map.getObjectTypeAt(i, j) === ‘exit’) {
continue;
}

var rv = Math.random();
if (rv < 0.45) {
map.placeObject(i, j, ‘tree’);
}
}
}
map.refresh();
};

functionList[‘movePlayerToExit’] = function () {
map.writeStatus(“Permission denied.”);
}

functionList[‘pleaseMovePlayerToExit’] = function () {
map.writeStatus(“I don’t think so.”);
}

functionList[‘movePlayerToExitDamnit’] = function () {
map.writeStatus(“So, how ’bout them <LOCAL SPORTS TEAM>?”);
}

// generate forest
functionList[‘generateForest’]();

// generate fortresses
functionList[‘fortresses’]();
functionList[‘fortresses’]();
functionList[‘fortresses’]();
functionList[‘fortresses’]();

map.getPlayer().setPhoneCallback(functionList[“generateForest“]);

map.placeObject(map.getWidth()-1, map.getHeight()-1, ‘exit’);
}

function validateLevel(map) {
map.validateAtLeastXObjects(100, ‘tree’);
map.validateExactlyXManyObjects(1, ‘exit’);
}

Chapter 9 – fordingTheRiver

This puzzle, I think I solved it in a weird way. I noticed that you can just map.defineObject() whatever you want, apparently. So I just defined an object called “bridge”, and walked across that.

I would think another way to solve this one would be with something like “if player.getY() == raft.getY() { raftDirection = “up”;}”

/**********************
* fordingTheRiver.js *
**********************
*
* And there’s the river. Fortunately, I was prepared for this.
* See the raft on the other side?
*
* Everything is going according to plan.
*/

function startLevel(map) {
var raftDirection = ‘down’;

map.placePlayer(map.getWidth()-1, map.getHeight()-1);
var player = map.getPlayer();

map.defineObject(‘raft’, {
‘type’: ‘dynamic’,
‘symbol’: ‘▓’,
‘color’: ‘#420’,
‘transport’: true, // (prevents player from drowning in water)
‘behavior’: function (me) {
me.move(raftDirection);
}
});

map.defineObject(‘water’, {
‘symbol’: ‘░’,
‘color’: ‘#44f’,
‘onCollision’: function (player) {
player.killedBy(‘drowning in deep dark water’);
}
});

for (var x = 0; x < map.getWidth(); x++) {
for (var y = 5; y < 15; y++) {
map.placeObject(x, y, ‘water’);
}
}

map.placeObject(20, 5, ‘raft’);
map.placeObject(0, 2, ‘exit’);
map.placeObject(0, 1, ‘block’);
map.placeObject(1, 1, ‘block’);
map.placeObject(0, 3, ‘block’);
map.placeObject(1, 3, ‘block’);

map.defineObject(‘bridge’, {
‘type’:’dynamic’,
‘symbol’: ‘░’,
‘color’: ‘#eee’,
‘transport’:true,
‘behavior’:function(){null;}
});
for (i = 6; i < 15; i++) {
map.placeObject(20,i,’bridge’);
}

}

function validateLevel(map) {
map.validateExactlyXManyObjects(1, ‘exit’);
map.validateExactlyXManyObjects(1, ‘raft’);
}

Chapter 10 – ambush

This one lets you change how the drones move…. so I changed how the drones move.

/*************
* ambush.js *
*************
*
* Oh. Oh, I see. This wasn’t quite part of the plan.
*
* Looks like they won’t let you take the Algorithm
* without a fight. You’ll need to carefully weave your
* way through the guard drones.
*
* Well, time to improvise. Let’s mess with their programming
* a little, shall we?
*/

function startLevel(map) {
function moveToward(obj, type) {
var target = obj.findNearest(type);
var leftDist = obj.getX() – target.x;
var upDist = obj.getY() – target.y;

var direction;
if (upDist == 0 && leftDist == 0) {
return;
} if (upDist > 0 && upDist >= leftDist) {
direction = ‘up’;
} else if (upDist < 0 && upDist < leftDist) {
direction = ‘down’;
} else if (leftDist > 0 && leftDist >= upDist) {
direction = ‘left’;
} else {
direction = ‘right’;
}

if (obj.canMove(direction)) {
obj.move(direction);
}
}

map.defineObject(‘attackDrone’, {
‘type’: ‘dynamic’,
‘symbol’: ‘d’,
‘color’: ‘red’,
‘onCollision’: function (player) {
player.killedBy(‘an attack drone’);
},
‘behavior’: function (me) {
            if (me.canMove(‘up’)){me.move(‘up’);
} else { me.move(‘left’);}

}
});

map.defineObject(‘reinforcementDrone’, {
‘type’: ‘dynamic’,
‘symbol’: ‘d’,
‘color’: ‘yellow’,
‘onCollision’: function (player) {
player.killedBy(‘a reinforcement drone’);
},
‘behavior’: function (me) {
            if (me.canMove(‘up’)){me.move(‘up’);
} else { me.move(‘right’);}

}
});

map.defineObject(‘defenseDrone’, {
‘type’: ‘dynamic’,
‘symbol’: ‘d’,
‘color’: ‘green’,
‘onCollision’: function (player) {
player.killedBy(‘a defense drone’);
},
‘behavior’: function (me) {
           if (me.canMove(‘up’)){me.move(‘up’);
} else { me.move(‘left’);}

}
});

// just for decoration
map.defineObject(‘water’, {
‘symbol’: ‘░’,
‘color’: ‘#44f’
});

map.placePlayer(0, 12);

for (var x = 0; x < map.getWidth(); x++) {
map.placeObject(x, 10, ‘block’);
map.placeObject(x, 14, ‘block’);

for (var y = 20; y < map.getHeight(); y++) {
map.placeObject(x, y, ‘water’);
}
}

map.placeObject(23, 11, ‘attackDrone’);
map.placeObject(23, 12, ‘attackDrone’);
map.placeObject(23, 13, ‘attackDrone’);

map.placeObject(27, 11, ‘defenseDrone’);
map.placeObject(27, 12, ‘defenseDrone’);
map.placeObject(27, 13, ‘defenseDrone’);

map.placeObject(24, 11, ‘reinforcementDrone’);
map.placeObject(25, 11, ‘reinforcementDrone’);
map.placeObject(26, 11, ‘reinforcementDrone’);
map.placeObject(24, 13, ‘reinforcementDrone’);
map.placeObject(25, 13, ‘reinforcementDrone’);
map.placeObject(26, 13, ‘reinforcementDrone’);

map.placeObject(map.getWidth()-1, 12, ‘exit’);
}

function validateLevel(map) {
map.validateExactlyXManyObjects(1, ‘exit’);
}

Untrusted Javascript Game Solutions – Chapters 6 – 10
Tagged on:                     

Leave a Reply

Your email address will not be published.