因为能独立玩通关这款游戏的人,要么是一名优秀的程序员,要么已经具备了优秀程序员的编程能力,转行做程序员的话,月薪绝对轻松过万。
这是一款模拟编程的手机游戏,名叫「人力资源机器」(英文名 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;
}
我单独列这条出来,就是想告诉编程爱好者们,千万不要灰心和气馁,只要保持兴趣和持续地学习,终究都能够掌握。
当然,如果实在是很想通关,又觉得身体被掏空力不从心的话,可以给「猫哥学前班」留言,我会把我的解题思路和答案发出来给大家参考。