因為能獨立玩通關這款游戲的人,要么是一名優秀的程序員,要么已經具備了優秀程序員的編程能力,轉行做程序員的話,月薪絕對輕松過萬。
這是一款模擬編程的手機游戲,名叫「人力資源機器」(英文名 Human Resource Machine)。由于關卡難度遞進的很合理,所以也可以作為一門學習編程(有點類似匯編)的課程來玩。
我們先來感受下這詭異的情節和畫風:
接下來,我來做個簡短的介紹,幫助「完全不會編程」又想學編程的同學入個門先。
游戲最基本的玩法是:每次執行 「inbox」命令時,小人會取出左側 INBOX 中最上面的一個方塊放在手中,每次執行「outbox」命令時,小人會把手中的方塊放到右邊的 OUTBOX(輸出)上。玩家需要按照任務的要求,把所有 INBOX 中的值一個個經程序正確處理后,輸出到 OUTBOX 中去。
實現方式如上圖所示,將「命令語句」中的多個命令按一定的順序拖入到「程序主體」中,完成后按下「執行」按鈕,這些命令就會以「從上到下」的順序一步步執行(注意函數體前面的 01、02、03…… 這些數字我們在程序中稱為「行號」)。如果執行的結果(即,放在「輸出」帶上的方塊)不滿足任務的要求,老板就會給出相應的提示,此時可以按下「停止」按鈕,重新調整「程序主體」后,再次嘗試執行。
上圖中間有標號的地板區域為臨時中轉區,通過「copyfrom」(把某個格子的方塊復制到手中)、「copyto」(將手中的方塊復制一份到某個格子中去)語句可以在這塊區域存放程序臨時的計算結果,這個區域有點類似電腦「CPU寄存器」和「內存地址」。
對于零編程基礎的玩家來說,想玩通關這個游戲,需要了解以下三個概念:
程序中的因果輪回
由于我們人類能感知時間的流逝,所以我們有「因果認知論」,前一秒發生的某件事會導致下一秒某件事情的發生,我們把前面的事件稱為「因」,后面的事件稱為「果」。
「因果決定論」在計算機程序中的表現形式就是「if 條件語句」。例如,把本文的標題用「程序」表達出來,就是下面這段代碼:
if( 能把游戲玩通關 ) {
那么就能成為程序員;
}
if( 是程序員 ){
那么就能月薪過萬;
}
這個游戲中有兩個 if
條件語句,它們分別是 「jump if zero」(如果為「零」則跳轉至)、「jump if neg」(如果為小于零的「負數」則跳轉至)。其中的「jump」(跳轉至)既可以跳轉到當前語句之前(過去的時間),也可以跳轉至當前語句之后(未來的時間)。
當跳轉至當前語句之前(過去)時,程序會按照「行號」(即,時間線)繼續從上到下執行,那就可能會再次執行到之前的「jump」語句,從而實現了一個「循環」重復的效果。我們也可以把它理解成「輪回」。
電腦和人類相比,有兩個明顯的優勢,一個是超快的運算速度和能力,另一個就是「能重復地、循環地甚至是永無止境地做某件事情」,就像希臘神話中那個不斷把石頭從山腳下搬到山頂上的「西西弗斯」一樣。
在一般的編程語言中,會有專門的 for
、while
語句來實現循環的功能,但在這個游戲中,我們需要借助「jump」來模擬實現,所以說這個游戲更像一門簡易的匯編語言。
引用
如果前面介紹的都看懂了,那應該能順利玩到「第 29 關 倉庫樓層」,到這一關之后,針對「copyfrom」和「copyto」命令,出現了一個新的特性:地址引用。
如圖所示,點擊「copyfrom」命令結尾的開關后,語句會在 copyfrom 10
和 copyfrom [10]
兩種形式之間切換。
這兩種形式的區別是,copyfrom 10 表示將地板上,下標為 10 的格子上的方塊復制到手中;copyfrom [10] 表示找到地板上下標為 10 的格子上的方塊的數字后,再次在地板上找到下標為這個數字的格子上的方塊復制到手中。我們也可以這樣理解:**copyfrom [10] 等效于 copyfrom (copyfrom 10) **。
在一般的編程語言中,會有一類數組類型的數據,可通過[]
中括號運算符來引用對應下標的數組元素。例如以下代碼的含義是:
a = [1,2,3];
b = a[0];
把一個有 3 個元素的數組賦值給變量 a,把變量 a 所指向的數組的下標為 0 (編程語言中數組的下標從 0 開始,它指向數組的第一個元素)的數字賦值給變量 b,所以 b 實際上等于 1。
零編程基礎同學請注意,以上等于號「=」與數學中的「=」含義是不同的,在程序代碼中一個「=」號叫做「賦值」(即,把「右邊的值」賦給「左邊的變量」),兩個等于號「==」才是「等于」的意思。
算法
當游戲中的王五跳樓之后,游戲難度上升到了最高層級,即使你已經很清楚所有命令的使用方法,但要完成關卡的任務卻絕非易事,需要超強的邏輯分析和推演能力才行。
這其中還會涉及到程序「算法」方面的知識,在編程領域有很多優秀的算法由早期的計算機大神們總結而來(可以看下這個「插入排序算法」的視頻了解下什么是算法,這個也是本游戲最后一題的解法),而這些知識點許多普通程序員也沒能掌握好。
// JavaScript 插入排序算法參考
function insertion(input) {
for(var i = 1, len = input.length; i < len; i++) {
for(var j = i; j > 0; j--) {
if(input[j] < input[j - 1]) {
input[j] = [input[j - 1], input[j - 1] = input[j]][0];
}
}
}
return input;
}
我單獨列這條出來,就是想告訴編程愛好者們,千萬不要灰心和氣餒,只要保持興趣和持續地學習,終究都能夠掌握。
當然,如果實在是很想通關,又覺得身體被掏空力不從心的話,可以給「貓哥學前班」留言,我會把我的解題思路和答案發出來給大家參考。