论程序猿的自我修养2-人力资源机器&七十亿人类、、、
女神拉克西丝吧
全部回复
仅看楼主
吧务
level 14
从前(转眼十年了)发过一个编程游戏Jahooma's Logicbox,这次是狂三推荐的两个编程游戏,人力资源机器(Human Resource Machine)和七十亿人类(7 Billion Humans)。
这两个游戏属于同一个系列,七十亿人类是人力资源机器的续作,两个游戏的玩法比较类似,主要是指令集不同。
2024年10月21日 10点10分 1
吧务
level 14
人力资源机器
第1年 收发室
第一部的核心就是输入和输出这两条传送带,从输入的传送带获取数据,经过处理后送到输出的传送带上,无论中间过程如何,只要输出是
正确的
就可以过关。
第一关就是两个最基础指令的用法:INBOX(输入)和OUTBOX(输出),任务也很简单,只要把输入的三个数据原样输出即可。
解法是唯一的,而且非常明确。
每关除了基础目标,还有两个附加挑战,一个是代码行数,另一个是运行步数,两个挑战也都完成才算完美过关。
刚开始玩是这两个挑战任务是隐藏的,只有过了几关之后才会显示,包括前面的关卡,这时候你才会发现,第2关居然没有完美过关。
两个挑战任务可以两组用不同的代码分别完成,因为有时候两个目标是互斥的,想要代码短,步数就会多,而想要步数少,代码就会长。
当然第一关不用考虑那么多,因为解法唯一,挑战肯定是完成的。
2024年10月21日 10点10分 2
吧务
level 14
第2年 繁忙的收发室
这次多了一个新指令:JUMP(跳转)。有了JUMP,就可以写循环了。虽然现在只能写死循环,但是不用担心,代码运行结束条件有两个,一是运行到结尾,后面再没有代码了;二是到了INBOX指令的时候发现输入栏已经空了。所以虽然是死循环,其实还是能结束的。
任务和上一关类似,把输入的数据全部原样输出。
3条指令做一个死循环,这是很自然的。
结果惊讶的发现,虽然代码行数完成了挑战,但是步数却没有完成。
这就是前面说的,两个目标可能会互斥,如果只用三行代码,步数无论如何也不可能再节省了,只能多写几行来解决这个问题。
为什么是30步呢?这其中包括了10个输入,10个输出,还有10个跳转,没错,每次跳转都是占步数的,输入和输出不可能节省,那就只还减少跳转次数,写成下面这样就好了,每输入输出2次只跳转1次:
当然如果愿意的话,还可以通过继续增加行数来减少步数,但是这里我就不折腾了。
2024年10月21日 10点10分 3
吧务
level 14
第3年 复印楼层
内存出现了,虽然空间很有限,地毯上的数据相当于内存,而手中的数据就相当于寄存器了。本关新增指令COPYFROM(读取),从内存中把数据复制到寄存器中。
任务是从内存中读取BUG三个字母并输出。
和第1关一样,解法基本是唯一的。
2024年10月21日 10点10分 4
吧务
level 14
第4年 扰码处理器
本关新增指令COPYTO(写入),把寄存器数据复制到内存中。
任务是把输入数据两两交换顺序然后输出。
因为寄存器位置只有一个,如果连续执行两次输入,第一个输入数据就会丢失,为了解决这个问题,第一个数据要先在写到内存中,等到把第二个数据输出之后,再读取出来输出。
2024年10月21日 10点10分 5
吧务
level 14
第5年是过场剧情,虽然一共有42年,其实过场剧情占6年,相当于实际36个关卡。
第6年 多雨之夏
新增指令ADD(加法),可以把内存中的数据加到寄存器中。
任务是把每两个输入数据加起来然后输出。
解法也很明确。
2024年10月21日 10点10分 6
吧务
level 14
第8年 三倍扩大室
第8、10、12年是支线关卡,主线解锁顺序是6-7-9-11-……,支线则是6-8-10-12,支线没有新增指令,只是使用原有指令完成一些更难的任务而已。为了更符合逻辑顺序,我打算先写完这条支线,然后再写第7年。
任务是把输入数据乘3再输出。
没有乘法指令,以后也不会有的。乘法只能用加法来实现,乘3就是加2次自己。
2024年10月21日 10点10分 7
吧务
level 14
第10年 八倍扩大装置
这次的任务是×8了。
×8当然也可以用7次加法实现,但这显然不是最简单的,我们可以把×8变成×2×2×2,这样就简单一些了。
不过有个很有意思的地方,×4直接用三次加法和两次乘法是一样快的,所以这里我就用三次加法了。
2024年10月21日 10点10分 8
吧务
level 14
第12年 四十倍扩大器
这次的任务已经变成×40了。
×40也就是×5×8,×8在上一关已经做出来了,而×5,还是四次加法吧,其他方法也不会更快了。
2024年10月21日 10点10分 9
吧务
level 14
第7年 零扑灭行动
本关新增指令JUMP IF ZERO(零跳转),如果寄存器的数据是0就跳转,否则继续执行后面的代码,有了这个指令就可以写分支或者不死的循环了。
任务是把输入中所有非0数据输出,0就不管了。
就是在之前输入输出的基础上再加一道判断,如果是0就跳过输出,直接进入下一轮输入。
2024年10月21日 10点10分 10
吧务
level 14
第9年 零保护行动
这次和上一关恰恰相反,只输出0,非0数据扔掉。
类似的思路写出来就是这样:
代码行数已经达标了,但是步数居然比目标多了3步。
很多时候我都感觉如果除了JZ有个JNZ就好了,但是没有。事实上,因为跳转占用步数,跳转指令太多的代码往往有优化空间,通过调整顺序就能减少几步。所以我最终想出了这样一种顺序,成功减少了步数。
2024年10月21日 10点10分 12
吧务
level 14
第11年 加运算走廊
不知道为什么起这个名字,本关明明是做减法的。
新增指令SUB(减法),用寄存器中的数数据减去内存中的数据。
任务是每两个数据,先用后者减前者,再用前者减后者,分别输出结果。
还是没什么多说的。
2024年10月21日 10点10分 13
吧务
level 14
第13年 均衡之间
新增了注释功能,注释不占行数,也不占步数,可以随便用,唯一的问题是要手写。但是,我写代码从来不注释。
任务是判断两个数据是否相等,如果相等就输出,否则不管。
判断相等的办法就是做减法,然后判断结果是否等于0。
步数又超了一步,还是类似第9年的优化办法。
2024年10月21日 10点10分 14
吧务
level 14
第14年 最大值室
新增指令JUMP IF NEG(负跳转),如果寄存器中的数据<0就跳转,否则继续执行后面的代码。
全游戏三个跳转指令都到齐了,相当于汇编的JMP、JZ、JB三个指令,这三个就足够了,剩下的JNZ、JA、JAE、JBE都可以通过组合来实现,就是费点劲。
本关任务是输出每两个输入数据中较大的那个。
与上一关比较类似,比较大小的方式就是相减,然后判断正负。
2024年10月21日 10点10分 15
吧务
level 14
第17年 专属休息室
第15年是过场剧情。第17年是支线,所以还是把第17年放在第16年之前。
任务是判断两个输入数据正负是否相同,相同输出0,不同输出1。0和1已经提前放在内存里了,可以直接取用,重点还是在于判断正负。
没什么好办法,就是每个数分别判断正负,然后分成正正、正负、负正、负负四种情况。
这种方法比目标还少一行代码,但是步数却超了一步,我们可以利用这一行代码的裕量,多写一个输出,从而减少跳转。
2024年10月21日 10点10分 16
1 2 3 4 5 6 尾页