Post subject: Untrusted - the javascript code-editing puzzle adventure
Patashu
He/Him
Joined: 10/2/2005
Posts: 4017
http://alexnisnevich.github.io/untrusted/ You are trapped with the exit unreachable. However, your computer gives you access to the game's code, some of it still in an editable state. Perhaps you can code yourself a pathway... 21 levels. Previous knowledge of coding not required - there is enough code visible on each level to deduce the syntax of Javascript without having to refer to outside websites. Level 13 is the most difficult level, so don't get discouraged - Do all the googling and reading you need to for it. After level 13 it's smooth sailing. Expect 2-10 hours to complete.
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
HHS
Active player (282)
Joined: 10/8/2006
Posts: 356
The game crashes in Safari with "EvalError: The this value passed to eval must be the global object from which eval originated".
Tub
Joined: 6/25/2005
Posts: 1377
Is the computer cheating? In level 2 (the maze), I noticed that the maze fills the whole map with objects and I'm not allowed to overwrite any existing block with 'space' or 'exit'. Yet the predefined function continues to place an exit at a random position.. 13 is indeed difficult. I solved it using something similar to a "global variable" to save some state information. Is it possible without? Level 19 is throwing security errors and displays a black screen. I doubt that's intentional?
m00
Player (142)
Joined: 7/16/2009
Posts: 686
This is fun. I'm not so much trying to actually solve the levels, as much as find a single snippet of code that solves all of them. Should be doable. So far I've worked my ways through most levels by removing the exit and placing it near me. Some slight adaptions make it work for most levels. The problem lies in getting the computer and other items...
Patashu
He/Him
Joined: 10/2/2005
Posts: 4017
HHS wrote:
The game crashes in Safari with "EvalError: The this value passed to eval must be the global object from which eval originated".
Firefox and Chrome both work, if you need a suggestion.
Scepheo wrote:
This is fun. I'm not so much trying to actually solve the levels, as much as find a single snippet of code that solves all of them. Should be doable. So far I've worked my ways through most levels by removing the exit and placing it near me. Some slight adaptions make it work for most levels. The problem lies in getting the computer and other items...
I thought that shouldn't work because you're not allowed to remove an object once it's placed.
13 is indeed difficult. I solved it using something similar to a "global variable" to save some state information. Is it possible without?
If it is possible without, I'm impressed.
Level 19 is throwing security errors and displays a black screen. I doubt that's intentional?
That is not intentional. It should be displaying a web page.
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Banned User, Former player
Joined: 3/10/2004
Posts: 7698
Location: Finland
Tub wrote:
13 is indeed difficult. I solved it using something similar to a "global variable" to save some state information. Is it possible without?
Make the robot mirror your moves. I'm sure you can figure out how.
Player (142)
Joined: 7/16/2009
Posts: 686
var u=String['from'+'CharCode'](95); var g=map[u+'display'].game; if(g!=undefined){ g.inventory=['computer','phone','redKey', 'yellowKey','greenKey','blueKey','theAlgorithm']; g[u+'moveToNextLevel']();}
Player (55)
Joined: 11/28/2013
Posts: 118
Function('a','a&&a["\x5fjumpToNthLevel"](22)')(map["\x5fdisplay"].game)
Projects: Tetris DS Genesis Toys: Let the Toy Wars Begin
Patashu
He/Him
Joined: 10/2/2005
Posts: 4017
You guys are silly :D
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Player (142)
Joined: 7/16/2009
Posts: 686
scahfy wrote:
Function('a','a&&a["\x5fjumpToNthLevel"](22)')(map["\x5fdisplay"].game)
Well, if we're going that route... Function('a','a&&a.\x5fstart(22)')(map["\x5fdisplay"].game)
Player (55)
Joined: 11/28/2013
Posts: 118
Scepheo wrote:
scahfy wrote:
Function('a','a&&a["\x5fjumpToNthLevel"](22)')(map["\x5fdisplay"].game)
Well, if we're going that route... Function('a','a&&a.\x5fstart(22)')(map["\x5fdisplay"].game)
Even dumber: (a=map['\x5fdisplay'].game)?a['\x5fstart'](22):
Projects: Tetris DS Genesis Toys: Let the Toy Wars Begin
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
13: Well, I did it with not global state, but instead state attached to the robot object itself. Same deal, though. 19: What was the idea here? I just mashed on the keyboard a bit and it went on to the next level. 20: I know a few ways to solve this, but how are you supposed to solve it? Nothing I did seemed very straightforward or obvious.
Banned User, Former player
Joined: 3/10/2004
Posts: 7698
Location: Finland
natt wrote:
13: Well, I did it with not global state, but instead state attached to the robot object itself. Same deal, though.
I'm almost sure that the way I solved it (ie. make the robot mirror the player's moves) is the "main" intended solution. (It's also pretty short. Requires about 5 lines of code.)
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
Warp wrote:
natt wrote:
13: Well, I did it with not global state, but instead state attached to the robot object itself. Same deal, though.
I'm almost sure that the way I solved it (ie. make the robot mirror the player's moves) is the "main" intended solution. (It's also pretty short. Requires about 5 lines of code.)
Could I see that solution? I gave a similar solution a try, but wasn't able to make it quite so short.
Editor
Joined: 3/10/2010
Posts: 899
Location: Sweden
13: //remotecontrol ftw! if(player.getX()==1) { if(player.getY()==map.getHeight() - 1) me.move("up"); else if(player.getY()==map.getHeight() - 2) me.move("down"); else if(player.getY()==map.getHeight() - 3) me.move("left"); else if(player.getY()==map.getHeight() - 4) me.move("right"); }
Banned User, Former player
Joined: 3/10/2004
Posts: 7698
Location: Finland
natt wrote:
Could I see that solution? I gave a similar solution a try, but wasn't able to make it quite so short.
var px = map.getWidth() - player.getX(); var py = map.getHeight() - player.getY(); if(me.getX() < px) me.move('right'); else if(me.getX() > px) me.move('left'); else if(me.getY() < py) me.move('down'); else if(me.getY() > py) me.move('up');
Patashu
He/Him
Joined: 10/2/2005
Posts: 4017
Here's my awful Dijkstra's algorithm solution to 13: https://gist.github.com/anonymous/81d115d07d2924f03429
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Here's my solution per each level, minified for your convenience: Level 1 cellBlockA: Tip: Change the code that is on black background. Solution: /*delete everything*/ Level 2 theLongWayOut: Tip: Find a way to disable offending code. Solution: if(0) { ... } Level 3 validationEngaged: Tip: Change the location of the blocks. Solution: for(var n=104; n--; )map.placeObject(n>>4, n%16, 'block') Level 4 multiplicity: Tip: The map does not verify something that the other maps do. Solution: map.placeObject(45,20, 'exit') Level 5: Tip: use setSquareColor. Solution: map.setSquareColor(x,y,'gold') Alternative way of thinking: }}{{ // Now there's only one mine. For some reason though, this does not work. I suspect the game cheats somehow. Level 6: Tip: Add obstacles to the bot, paying attention to the route he takes. Solution: map.placeObject(22,10,'block'); // The player moves 8*down, then all the way to the right. Level 7 colors: Tip: Change player's color depending on their current color. Solution: for(var c=['#f00','#ff0','#0f0','#f00'],q=player,n=0;n<3;++n)if(q.getColor()==c[n]){q.setColor(c[n+1]);break;} Level 8: Tip: Try one of the functions. Solution: generateForest Level 9: Tip: --- Solution: map.getPlayer().setPhoneCallback(function(){raftDirection='up'}) Level 10 ambush: Tip: --- Solution: moveToward(me,'reinforcementDrone');me.move('left') |||| me.move('up') |||| me.move(Math.random(0,1)<.5?'up':'right') Level 11: Tip: --- Solution: me.move(me.canMove('right')?'right':'down') Level 12: Tip: --- Solution: if(typeof me.xp == 'undefined') me.xp = 0; me.xp += 1; if(me.xp & 1) me.move('right'); else if(me.xp < 30) me.move('down'); else if(me.xp < 70) me.move('up'); else me.move('down'); (probably not intended) Level 13 robotMaze: Tip: Find a way to tie the bot's movements to things the player can control. Solution: var d=['right','left','down','up'],p=player; me.move(d[(p.getY()&2) + ((p.getX()&2)>>1)]) // Or you could use Djikstra's algorithm as Patashu did :-) Alternative solution that does not involve either polling the player or reading the map beforehand, yet is guaranteed to solve the maze: function c(x,y) { return 'c'+(x+me.getX())+'|'+(y+me.getY()) } if(typeof me.know=='undefined')me.know={} var dirs={'up':c(0,-1),'down':c(0,1),'left':c(-1,0),'right':c(1,0)} var here=c(0,0), k=me.know, next='', best=-99, p if(typeof k[here] == 'undefined') k[here]=0; --k[here]; for(var d in dirs) if(me.canMove(d)) { if(typeof k[p = dirs[d]] == 'undefined') k[p] = 0; if(k[p] >= best) { next=d; best=k[p]; } } me.move(next) Level 14: Tip: --- Solution: greenKey');map.placeObject(24,9,'yellowKey |||| Path: redLock redKey greenLock blueKey and the rest is obvious (This probably wasn't the intended solution.) Level 15 exceptionalCrossing: Tip: --- Solution: )},'onCollision':function(){Math.random( (This is what most people did, I hear. Nevertheless, it is probably not the intended solution.) Here's what I tried first, but alas, the limit is a few letters too short: )}});return;map.placeObject(2,2,'exit',function(){{x( Shorter solution (thanks Warp!) -- probably abuses a bug, or maybe it is even the intended solution: map.x() Level 16 lasers: Tip: --- Solution: color |||| var n=0,p=map.getPlayer(); p.setPhoneCallback(function(){p.setColor(colors[++n%3])}) Level 17 pointers: Tip: Remember setSquareColor? Solution: f(t1.getType()=='teleporter' && t2.getType()!='teleporter') map.setSquareColor(t1.getX(),t1.getY(),'#800'); if(t2.getType()=='teleporter' && t1.getType()!='teleporter') map.setSquareColor(t2.getX(),t2.getY(),'#800'); Level 18: Tip: Remember placeObject? Solution: map.placeObject(player.getX()+1,player.getY()+1,'block') // Instead of jumping, you are creating a bridge... Level 19: Tip: --- Solution: Just press random directional buttons and the next level comes up very soon without need to understand a thing about this level. Level 20 bossFight: Tip: There's a reason why the boss creates bullets y+2 from their own position. Solution: var p = map.getPlayer(),o=map.placeObject; o(30,20,'block'); map.defineObject('freedom', { 'type': 'dynamic', 'symbol': '<', 'color': 'green', 'interval': 100, 'projectile': true, 'behavior': function (me) { me.move('left') } }); p.setPhoneCallback(function(){ o(p.getX()-1, p.getY() , 'freedom'); }); // Use the single block of cover to get the phone. Then move to the top of the screen and begin the massacre. Funny observation: Instead of blocks, which are counted and limited to one, you can create an unlimited number of trees that work the same way as blocks. Level 21: Tip: Open the menu. Solution: Open menu, open objects.js, remove the single exclamation mark. Level 22: Tip: The game ends. Solution: The game ends.
Editor
Joined: 3/10/2010
Posts: 899
Location: Sweden
More intended solution for 15: function () { throw ""}() Short and to the point. 16: Rather straight forward task. var playerColorId=0 function p() { playerColorId=(playerColorId+1)%3 map.getPlayer().setColor(colors[playerColorId]); } map.getPlayer().setPhoneCallback(p) 17: if(t1.getType() == 'teleporter' && t2.getType() == 'teleporter') { p1=map.getCanvasCoords(t1) p2=map.getCanvasCoords(t2) c=map.getCanvasContext(); c.moveTo(p1.x,p1.y); c.lineTo(p2.x,p2.y); c.stroke(); c.strokeStyle="white"; } 18: Hold right and don't write any code! Quite the disappointing level. 19: Assuming that the AI opponent remains stuck at the start due to incompetence: Up x4, right x2, down x1, right x1, down x1, right x1, down x1
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
This elaborate code for level 17 (pointers) calculates and highlights the actual solution to the puzzle. Surprisingly most of the puzzles it generates are actually unsolvable. You have to click Execute a few times to get a solvable one. https://gist.github.com/a4afaa46b0672ba781d0 (Thanks henke37 and Patashu for the ideas.)
henke37 wrote:
18: Hold right and don't write any code! Quite the disappointing level.
Didn't work for me. Must be a browser-dependent issue.
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
Level 15, this seemed like the "obvious" solution to me: https://gist.github.com/anonymous/4490c3d8591191db1c98
Spikestuff
They/Them
Editor, Publisher, Expert player (2297)
Joined: 10/12/2011
Posts: 6337
Location: The land down under.
If I knew Java I would be doing this... but I don't.
WebNations/Sabih wrote:
+fsvgm777 never censoring anything.
Disables Comments and Ratings for the YouTube account. Something better for yourself and also others.
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Spikestuff wrote:
If I knew Java I would be doing this... but I don't.
It is not Java. It is Javascript, which is a completely other language. Additionally, as Patashu pointed out in the first post, if you know the principles of programming in general, you can always infer enough syntax from the surrounding code that you can get by without knowing any Javascript beforehand.
Player (79)
Joined: 8/5/2007
Posts: 865
Bisqwit wrote:
Spikestuff wrote:
If I knew Java I would be doing this... but I don't.
It is not Java. It is Javascript, which is a completely other language. Additionally, as Patashu pointed out in the first post, if you know the principles of programming in general, you can always infer enough syntax from the surrounding code that you can get by without knowing any Javascript beforehand.
You'd think so, but I had a very hard time making significant progress in this game. I was able to reach level 9 on my own and get to level 10 by looking up level 9's solution. I got hung up on some very simple concepts. For example, many of your solutions (and some of the game's code) involve the object (?) "me". What exactly is "me"? The player? If so, that seems redundant and confusing. I also noticed that your solution to level 7 was cut down to a few lines by use of an array. I didn't know how to construct arrays in JavaScript, so my solution was much less elegant. On level 9, I copied "player.setPhoneCallback()" directly from the API and it gave me an error message:
TypeError: player.setPhoneCallback is not a function
Your code instead uses map.getPlayer().setPhoneCallback. Honestly, how was I supposed to know to use that? You also use an anonymous function, which I wouldn't confidently leap upon in a programming language I've never used before. Don't get me wrong. I liked the game. It was fun and I was pleased to get as far as I did on my own and it did serve as a nifty introduction to JavaScript. I just don't think that it's as easy to pick up from scratch as you say.
Editor
Joined: 3/10/2010
Posts: 899
Location: Sweden
Variable scope isn't a strange thing.