春節(jié)在家寫代碼——編程游戲深度推薦(上)

作者:馬瑤
春節(jié)難得有個長假,先在這里給大家拜年了。

過去的一年里,大家做游戲的水平有沒有提高呢?
咱們的游戲開發(fā)群里已經(jīng)有幾千名愛好者,許多學習順利的同學已經(jīng)有了飛速進步;而學習進展不順的同學可能還在苦苦鉆研之中。
陷入瓶頸的時候,不妨嘗試換個方法學習,說不定就能有所突破。所以趁著新春的躁動,為大家深度推薦兩個編程游戲。
一個是2015年發(fā)布的老游戲《程序員升職記》(又名Human Resource Machine,人力資源機器),一個是幾個月前發(fā)布的新游戲,也是前者的續(xù)作,名為《70億人》(7 Billion Humans)。
游戲算不上很新,但是好東西永遠也不會過時。我打算從專業(yè)性的角度來介紹真實編程與游戲之間的關系,希望能讓大家體會到“編程”這種高端解謎游戲的樂趣。
另外由于很多人已經(jīng)接觸過《程序員升職記》,所以我附上了可運行的C語言代碼(文末可下載源碼),爭取讓玩過游戲的人看完本文也能有所收獲。
1. 基本輸入輸出,無限循環(huán)

《程序員升職記》第2關,將輸入欄中所有方塊都放到輸出欄里。
inbox可以用來從輸入欄(左邊的傳送帶)拿出一個方塊。
outbox可以將手上的方塊放在輸出欄(右邊的傳送帶)上。
jump可以讓程序跳轉到任意一個位置。
思路就是取一個、放一個、然后回到第一步無限循環(huán)。等價的C語言代碼:
// 模擬游戲的輸入欄
char* inbox[] = {"A", "U", "T", "O", "E", "X", "E"};
void Level2()
{
?????? while(true)
?????? {
????????????? bool b = false;
????????????? int out = 0;
????????????? // b用來區(qū)分數(shù)字還是字母
????????????? b = INBox(&out);
????????????? OUTBox(b, out);
?????? }
}
?
2. 變量:地板,數(shù)據(jù)的臨時存放處

第3關,不用管輸入,輸出“BUG”即可。
copyfrom:將地板某個位置的方塊復制到手上一份。
思路是挑出B、U、G三個字母放在輸出欄。
等價的C語言代碼:
void Level3()
{
?????? char floor[] = {'U', 'J', 'X', 'G', 'B', 'E'};??
??? // false代表輸出字母
?????? OUTBox(false, floor[4]);
?????? OUTBox(false, floor[0]);
?????? OUTBox(false, floor[3]);
}
?
3. 加減法和條件跳轉語句

第14關,每次取出兩個數(shù)字,輸出其中較大的一個。連續(xù)操作直至用光輸入。
copyto:將手上的方塊拷貝到地板指定位置。
add:將地板某個位置的數(shù)字與手上的數(shù)字相加,結果還在手上。
sub:同上,手上的數(shù)字減去地板的數(shù)字。
jump if zero:如果手上的數(shù)字是0,則跳轉,否則執(zhí)行下面一句。
jump if negtive:如果手上的數(shù)字是負數(shù),則跳轉,否則執(zhí)行下面一句。
思路:先取兩個數(shù)字,放在地板上,然后拿第二個數(shù)字減去第一個數(shù)字。
如果結果為負,說明第一個數(shù)字更大,取第一個數(shù)字輸出;否則取第二個數(shù)字輸出。
優(yōu)化方案:巧妙利用先減再加的方式,可以只用一塊地板。等價的C語言代碼:
void Level14()
{
?????? // 求最大值,只用人手和一塊地板
?????? int hand;
?????? int a;
?????? while (true)
?????? {
????????????? INBox(&hand);
????????????? a = hand;
????????????? INBox(&hand);
????????????? hand = hand - a;
????????????? if (hand < 0) {
???????????????????? hand = a;
????????????? }
????????????? else {
???????????????????? hand = hand + a;
????????????? }
????????????? OUTBox(true, hand);
?????? }
}
?
4. 高級語法:引用(下標)
這個游戲的代碼真的不好寫。一路燒腦之后,堅持到29關,會發(fā)現(xiàn)真正的高級抽象代碼登場啦!

第29關,輸入一個數(shù)字,以這個數(shù)字作為地板的編號,取出對應的字母,然后輸出該字母。
copyfrom和copyto出現(xiàn)新的變化:以前是直接指定地板編號?,F(xiàn)在如果對地板編號加上中括號,代表取該地板上的數(shù)字對應的地板。(思路上再間接一次,如果說“地板12”代表第12塊地板,那么“地板[12]”則代表地板12上面的方塊8,也就是指第8塊地板)。
等價的C語言代碼:
// 模擬游戲的輸入欄
char* inbox[] = {"4", "4", "1", "4", "1"};
void Level29()
{
?????? // 取地板上某一塊作為臨時變量
?????? int n;
?????? // 地板上的字符
?????? char floor[] = "NKAERDOLYJ";
?????? while (true)
?? {
????????????? INBox(&n);
????????????? // n 被作為下標使用
????????????? OUTBox(false, floor[n]);
?????? }
}
?
如果寫成C語言反而很好理解——不就是數(shù)組下標嘛。
但是放在游戲中,這種間接的思路絕對是打開了新世界的大門,對編程思維有極大鍛煉,強烈建議大家堅持玩過第29關。

玩到30關,真的會變強。
5. 終極操作:引用(下標)配合加減法

第30關,地板上放著一堆字母和0,每輸入一個數(shù)字,都從該數(shù)字代表的地板開始連續(xù)依次取字母并輸出,直到遇到0這一次操作結束。然后再不斷重復這種操作。
最終會得到一串連續(xù)的字符,也就是解密了密碼。
思路:這里并沒有新的指令,但是我們如果將數(shù)字的加減法與引用地板配合,就會爆發(fā)出強大的功能。
輸入一個數(shù)字,比如4,放在空的地板24上。
取地板[24],也就是4,并輸出。
利用bump+,加1操作,4+1=5。
回到第2步,這時變成了地板5。
反復2~4,直到取到了0為止。
等價C語言代碼:
char* inbox[] = {"4", "15", "7", "0", "21", "17", "11", "20", "2", "13", "4", "17", "21"};
void Level30()
{
?????? // 密碼破譯
?????? int n;
?????? char floor[] = "GET\0TH\0TAR\0AWAKE\0IS\0XXX\0";
?????? while (true)
?????? {
????????????? INBox(&n);
????????????? while (true)
????????????? {
???????????????????? OUTBox(false, floor[n]);
???????????????????? n++;
???????????????????? if (floor[n] == '\0') { break; }??????? // 注:C語言中,'\0'等于0
????????????? }
?????? }
}
?
代碼執(zhí)行過后,得到了字符串:

這句話聯(lián)系到了這個游戲最后的秘密,細思極恐啊。
《程序員升職記》的玩耍建議
1. 玩這個游戲真的可以學編程,強烈建議對編程和游戲開發(fā)感興趣的人玩一玩。這個游戲的算法覆蓋了大部分編程基礎內容,而且用這種類似“匯編”的代碼實現(xiàn)難度很不低,很鍛煉編程思維。
2. 這個游戲每關都有“強迫癥挑戰(zhàn)”,追求最小化代碼行數(shù)和最佳化執(zhí)行效率。也就是傳說中的“優(yōu)化”。
特別建議:一開始不要優(yōu)化!除非對于有余力的同學可以嘗試挑戰(zhàn),大部分人還是適合先把精力放在過關上面,玩到后面再回頭看前面的問題就會很簡單,到時候再優(yōu)化也不遲(也可參考網(wǎng)上的答案進行優(yōu)化,學習優(yōu)化技巧)。
3. 在選關界面,右側是主線,左側是支線。中后期支線難度非常大,建議以攻略主線為主。
4. 有人問通關游戲是什么水平?恭喜你,雖然寫真實的程序代碼還是需要花時間學習,但是至少在思維水平和解決問題的靈活性上,你已經(jīng)達到了相當不錯的水準,如果開始學習編程進展一定會很快~~
5. 對于計算機專業(yè)的大學生或者自學編程的同學,如果學完基礎知識但是不會做題,那就更要加倍推薦這個游戲了。
★ 本游戲有steam、wegame、手機版本,均支持中文。
參考答案有很多,請百度,比如百度經(jīng)驗就有:https://jingyan.baidu.com/article/ca00d56c26efaae99eebcfe4.html
務必在實在想不出來的時候再研究,或者學習別人的優(yōu)化技巧。不求通關,但求進步。
本篇內容有點多,續(xù)作《70億人》和其它編程游戲下期介紹(續(xù)作更精彩)。
本期源碼地址:http://link.zhihu.com/?target=https%3A//github.com/mayao11/CodeGames
想系統(tǒng)學習游戲開發(fā)的童鞋,歡迎訪問?http://levelpp.com/????????
游戲開發(fā)攪基QQ群:869551769? ?