這個游戲還不錯,用了兩個晚上的時間通過並寫下解法。這個游戲通過修改JS代碼來通關的游戲。很考驗玩家的解決問題能力,同時也有一定的可玩性。
游戲地址 http://alexnisnevich.github.io/untrusted/
第一關
游戲說明,先移動@符號到⌘,獲取一個功能窗口,然后右邊就會出現一段代碼,而該段代碼的執行結果呈現在左邊。現在要你移動@到口,要記住接下來的每一關都是要移動到藍色的方框中(口)。我們修改右邊的代碼,讓@符號可以找到出口。我在這一關的解法是:
然后按下面的Execute 或 Ctrl-5 進行運行,這是那些牆都不見了,我們就可以直接移到出口。這樣就完成了這一關。注意代碼的編寫這能在黑色的部分,紅色背景的代碼是不可以修改的。
而這些呢,一個是js會用到的API,第4個是重置,第五個是運行。
接下來,如果非必要我就不截圖了。
第二關
是一個隨機的迷宮。
解法是在兩個輸入的地方進行塊注釋
第三關
@在房間內,如何出來,沒錯,第一想法是要把中間兩個for都注釋掉,但是很遺憾失敗了,因為最下面的validateLevel方法已經規定了block(#)的個數了,所以注釋不了。那該如何解呢?
我的解法是將第一個for里面的代碼中的map.placeObject(5,y,’block’);改為map.placeObject(3,y,’block’);就可以了。修改后,然后execute運行。
第四關
@跳出房間,這次的牆都不能修改了,該怎么辦呢?我們先看一下API給我們提供了什么。
map.placeObject(x, y, objectType) //Places an object of the given type at the given coordinates.
這個API好像還不錯呢.我們可不可以在多創建一個出口呢,答案是可以的。
我的解法是創建多一個出口
Map.placeObject(40,20,’exit’);
第五關
Mine沒錯是雷,看一下代碼getRandomInt()函數就知道,這一關是隨機分布雷,然后要你在不踩到雷的情況下,到達出口。
我的解法是 看上面的map.setSquareColor()函數,不就是修改了顏色嗎?我也會,在輸入的地方輸入 map.setSquareColor(x,y, 'fff'); 就可以了
第六關
有個守衛d 會根據你的位置,然后靠近你,一旦跟他重疊就輸了。該怎么辦呢?方法還比較簡單,就是建一面牆,然后繞過去就可以了。

1 for(var x = 0; x < map.getWidth()-3; x++) { 2 map.placeObject(x, 2, 'block'); 3 } 4
5 for(var y=2;y<10;y++){ 6 map.placeObject(map.getWidth()-3,y,'block'); 7 }
第七關
這一關有個電話,撿起它后,你就會有一個調用函數的接口了,看下面的提示就知道,每次要按下Q鍵,就調用 player.setPhoneCallback() 回調函數。這一關是如果@和☒符號的顏色一樣就可以通過了。我們只要定義每次按下Q鍵就改變顏色就可以了。
代碼如下

1 var i=0; 2 if(player.getColor()=='#0f0'&&i==0) 3 { 4 player.setColor('#ff0'); 5 i++; 6 } 7
8 if(player.getColor()=='#ff0'&&i==0) 9 { 10 player.setColor('#f00'); 11 i++; 12 } 13 if(player.getColor()=='#f00'&&i==0) 14 { 15 player.setColor('#0f0'); 16 i++; 17 }
第八關
一看代碼,整個代碼段就那個函數是可以修改的。
把movePlayerToExit 改為 generateForest 就可以了。作用是每次按下Q鍵就隨機一次地圖,我們只要每次都移動一小點,慢慢的就可以到達了。注意如果你碰巧被#符號困住,那么你可以按Reset重置一下。
第九關
這一關是這樣的,要你跨過那些水,到達河的對面。
解法是用map.defineObject定義一條橋來讓player通過,按照上面提示的定義一個類似與raft的對象,只是這個對象就不要移動函數了,不然難以控制。
代碼如下

1 map.defineObject('aa',{ 2 'type':'dynamic', 3 'symbol':'||', 4 'color':'#ff0', 5 'transport':true
6 }); 7
8 for (var y = 5; y < 15; y++) { 9 map.placeObject(0, y, 'aa'); 10 } 11
12
第十關
這一關就是有很多的守衛,他們默認會向你移動。程序中就是要你修改他們默認的移動方法。該如何移動才不會碰到你呢?
看一下API 有個object.canMove();的函數
三個移動方法都寫上這個

1 if(me.canMove('up')){ 2 me.move('up'); 3 }else{ 4 me.move('right'); 5 }
第十一關
有個robot對象,然后要R這個移動到k那里,也就是讓機器人r找到鑰匙k,然后才可以讓你進入下一關。R機器人會把k給帶出來,然后你還要移動到R上面,拿到鑰匙,然后才出開門,進入下一關。
解法如下:

1 if(me.canMove('right')){ 2 me.move('right'); 3 }else{ 4 me.move('down'); 5 }
第十二關
這一關跟剛才那一關很相似。只不過是移動的時候有點難而已。最笨的辦法是手動模擬R的路徑出來就可以了。

1 if(me.getY()<9&&me.getX()<20){ 2 if(me.canMove('down')){ 3 me.move('down'); 4 }else{ 5 me.move('right'); 6 } 7 }else if(me.getX()>=20&&me.getX()<map.getWidth()-2){ 8 if(me.canMove('up')){ 9 me.move('up'); 10 }else{ 11 me.move('right'); 12 } 13 }else{ 14 me.move('down'); 15 }
第十三關
在上一關的基礎上又進一步了。我都不知道要怎么弄了。以前做這種迷宮的題都是dfs或bfs解決的。現在都不知道怎么下手了,要不用里面給的隨機移動,只要時間夠長,就一定能拿到key並出來。
這道題想了很久都沒有想出來,百度了一下,看了一下別人的解法。難題就在於在一個函數里面不能保存上一次的運行結果。如果可以,就可以通過獲取player這一次的xy位置,與下一次的xy位置進行判斷。但是這個變量怎么定義就成為了一個問題,因為每次都會定義一次。然后我就想到了用靜態變量,誰知js沒有靜態變量,這能通過全局變量。看了別人的解法,簡直被嚇尿了。居然用類似與數據庫注入的辦法。具體很難描述。直接上代碼

1 if (player.getX() - lx == 1) me.move('right'); 2 else if (player.getX() - lx == -1) me.move('left'); 3 else if (player.getY() - ly == 1) me.move('down'); 4 else if (player.getY() - ly == -1) me.move('up'); 5 lx = player.getX(); 6 ly = player.getY(); 7 } 8 }); 9
10 var lx = player.getX(); //這樣就有靜態變量了。
11
12 var ly = player.getY(); 13
14 map.defineObject('foo', { 15 'type': 'dynamic', 16 'dat': function() {
第十四關
這一關還是比較難,就是用同顏色的鑰匙開同顏色的鎖,然后最終拿到A並過關的意思。可以操作的地方不多,一看就是讓我們設置當開綠鎖的時候我們應該把哪把鑰匙獻上。要么是redKey要么是blueKey,greenKey。其實利用反推思想還是比較好做的。
我們選擇blueKey。
第十五關
接下來的一關比一關難了。要好好想想。看一下validateLevel和前面幾關有什么不同。
輸入代碼 map.placePlayer(0, 0) 就可以通關,也不知道為什么。
第十六關
我++這是什么,不是字符模式嗎?怎么是圖形的。什么要求啊,看一下代碼先…… 注釋完代碼后,以為可以了。唉,我還是太天真了。還是好好看代碼,分析一下
這關是隨機產生25條牆,不能刪除,因為validateLeve函數有驗證。每個牆壁有一種顏色,如果顏色與@相同就可以讓@通過。否則就失敗。
第一步先把顏色弄出來。
第一段代碼 ctx.strokeStyle=’white’ 該成 ctx.strokeStyle=color;
編寫一個setPhoneCallback函數的像第7關一樣。應該就可以了。
第二段代碼

1 var player = map.getPlayer(); 2 //map.placeObject(1, 1, 'phone');
3 player.setColor('red'); 4 player.setPhoneCallback(function(){ 5 var i=0; 6 if(player.getColor()=='yellow'&&i==0) 7 { 8 player.setColor('red'); 9 i++; 10 } 11 if(player.getColor()=='red'&&i==0) 12 { 13 player.setColor('teal'); 14 i++; 15 } 16 if(player.getColor()=='teal'&&i==0) 17 { 18 player.setColor('yellow'); 19 i++; 20 } 21 }); 22
顏色值要用字母代替。不能用十六進制。
第十七關
每一個方格里面有三個門,和三個*號,表示不能達到的。具體那些門可以進,那些門傳送到達*號,在代碼中已經有體現出來了。就是那個getType()還有setTarget()用來表示門之間的對應關系。
畫出來的圖是這樣的。然后自己找路走,很大的機率是走不通的,多execute幾次,總有一次是可以的。
代碼如下

1 if(t1.getType() == 'teleporter' && t2.getType() == 'teleporter') { 2 var t1p = map.getCanvasCoords(t1); 3 var t2p = map.getCanvasCoords(t2); 4 //canvas.fillStyle ='orange';// 'rgb(0,165,0)';
5 //canvas.strokeStyle = 'red';
6 //canvas.strokeStyle ="rgb(" + r + ", " + g + ", "+ b +")";
7 canvas.lineWidth = 1; 8 canvas.moveTo(t1p.x, t1p.y); 9 canvas.lineTo(t2p.x+5,t2p.y+5); 10 canvas.stroke(); 11 } 12
13 if(t1.getType() == 'trap' || t2.getType() == 'trap') { 14 var t1p = map.getCanvasCoords(t1); 15 var t2p = map.getCanvasCoords(t2); 16 //canvas.fillStyle ='orange';// 'rgb(0,165,0)';
17 canvas.strokeStyle = 'blue'; 18 //canvas.strokeStyle ="rgb(" + r + ", " + g + ", "+ b +")";
19 canvas.strokeStyle="rgba(0,0,222,0.1)"; 20 canvas.lineWidth = 2; 21 canvas.moveTo(t1p.x, t1p.y); 22 canvas.lineTo(t1p.x+5,t1p.y+5); 23 canvas.moveTo(t2p.x, t2p.y); 24 canvas.lineTo(t2p.x+5,t2p.y+5); 25 canvas.stroke(); 26 }
第十八關
這一關的意思就是跳過去,但是中間有個坑。怎么過呢,要你寫那個jump函數。
第一想法弄個 map.placeObject(1,1,’block’); 要弄一條橋。沒那么容易。不給造。
我發現快速的按下右還有上是可以前進一小段的。這個是不是可以利用一下。
我就編了一段腳本模擬鍵盤輸入右方向鍵。這不是正常的辦法,等我想到正常的辦法再給出代碼。這里先通關再說。
非正常方法
在Windows下,創建一個aa.vbs的文件里面寫上

1 Set objShell = CreateObject("Wscript.Shell") 2 WScript.Sleep 3000
3 for i=1 to 1000 '循環發送消息100次!
4 WScript.Sleep 1
5 objShell.SendKeys "{up}"
6 objShell.SendKeys "{up}"
7 objShell.SendKeys "{right}"
8 next
9
保存,然后雙擊運行aa.vbs,然后在3秒內移到游戲窗口。就可以通過。可能根據不同的機器,上面的參數會有所不同。
樓下給出的解法,不錯哦!

1 map.startTimer(realJumper, 45); 2 } 3 4 function realJumper(){ 5 if(player.getX()<fl(w/2) + 5)player.move("up");
第十九關
這一關我都不知道怎么回事,只是簡單的上下左右,幾次后就通關了。也沒有代碼。
第二十關
天上下着雨,我們要避開雨到達對面。我覺得我呢能力就到這里了。只能參考別人的解法了。
這一關是天降毒雨,我們必須頂着毒雨和上面的BOSS作斗爭,消滅所有的BOSS之后拿到A之后才能通關。翻API的時候發現有map.overrideKey這個函數,可以復寫一個方向鍵的回調函數,解決沒辦法觸發的問題。然后我們只要做向上發射的子彈去消滅BOSS就好了。這里因為我們要往右上下移動,所以選擇復寫了左方向鍵。

1 map.defineObject('arrow', { 2 'type': 'dynamic', 3 'symbol': '↑', 4 'color': 'green', 5 'interval': 100, 6 'projectile': true, 7 'behavior': function (me) { 8 me.move('up'); 9 } 10 }); 11
12 function shoot() { 13 for (x = 0; x < map.getWidth(); x++) { 14 map.placeObject(x,12,'arrow'); 15 } 16 } 17
18 map.overrideKey('left', shoot);
第二十一關
這一關應該就是最后一關了。這一關我也不會做,還是看別人的做法。
這一關什么阻礙都沒有,然后你也不可以操作代碼,但是就是沒法過關。看代碼的原因應該是map.finalLevel這個值變成True了表示最后一關,所以就沒辦法再下一關了。
最后搜索了一下發現原來Menu界面下可以查看scripts文件夾,有看過游戲的Github地址,才知道這是游戲的源碼了。而且發現有幾個文件是呈黑色的,似乎可以修改的說。這一關我估計就是作者要玩家讀懂整個程序。然后了解。
解法
進Object.js文件修改exit對象的行為判斷函數,把if(!map.finalLevel){}去掉就好了。
第二十二關
結束了。
每一關的解法其實都是有保存的,保存在https://gist.github.com/******* 中
1. https://gist.github.com/dab3fa8d760afaa7be5b
2. https://gist.github.com/c71fe3495da61f413413
3. https://gist.github.com/88bd05ee27de9bece74a
4. https://gist.github.com/0a903137d4d5c756edf6
5. https://gist.github.com/1c30585f8498cff31566
6. https://gist.github.com/cc226fce4d1fda3d1ea8
7. https://gist.github.com/9c084e394ecc83fca6a0
8. https://gist.github.com/64963dbaef590cc5f769
9. https://gist.github.com/f0943f451c6a753cce9d
10. https://gist.github.com/00f663b522a8ed61431e
11. https://gist.github.com/3bc8c18cb8ea08c44714
12. https://gist.github.com/6e5679bc8e49ace815cc
13. https://gist.github.com/f157a0b23f4c9edfcd45
14. https://gist.github.com/b32d662528a577262255
15. https://gist.github.com/ec012bbc94a87678d743
16. https://gist.github.com/cf063c4a718da051c55a
17. https://gist.github.com/007211c7698b41d2225f
18. https://gist.github.com/d6491415365bc658f180
19.
20. https://gist.github.com/9f0f5022f03fbb313529
21. https://gist.github.com/440c4ca348a605f839b5
參考方案: http://blog.segmentfault.com/openwrt/1190000000467496
***********************************************