<p class="ql-block"><a href="https://www.meipian14.cn/532qteeu" target="_blank" data-link="create">《图灵完备/Turing Complete》游戏攻略(2)</a></p> <p class="ql-block"><b>《图灵完备/Turing Complete》游戏攻略(1)</b></p> <p class="ql-block"><b>前言</b></p><p class="ql-block">你可以通过《图灵完备》这款游戏,学习处理器架构,搭建自己的伟大作品。游戏闯关模式的最终目标是搭建一台可以运行的计算机。这里将转载这款游戏的攻略,详细解析每一关的通关思路,并且讲解背后的原理。</p> <p class="ql-block"><b>第一章:基础逻辑电路</b></p><p class="ql-block"><b>前言</b></p><p class="ql-block">我们进入了第一章:基础逻辑电路。在这一章中,我们会搭建出所有常用的逻辑门。</p><p class="ql-block"><b>原力觉醒</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">在这关中我们学会了连接导线,把输入与输出连接在一起即可。</p> <p class="ql-block">本关最终答案</p> <p class="ql-block"><b>与非门(NAND)</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关的问题是“电路中的与非门有什么效果”,其实就是要让我们探索与非门的性质。</p><p class="ql-block">我们先了解什么是真值表,它由输入和输出构成,它展示的是当电路的输入是什么,对应的输出是什么。</p> <p class="ql-block">我们只需要开关左上角的输入,查看输出的结果,填写真值表,即可。比如我们先把两个都调为红色,发现结果是绿色,则在输出里的第一列填写绿色。</p><p class="ql-block">边测试边填写,理解与非门的原理,理解真值表是什么,填写完后即可过关。</p> <p class="ql-block">本关最终答案</p> <p class="ql-block"><b>与非门(NAND)</b></p><p class="ql-block">这关中我们理解了与非门,与非门是逻辑门的一种,它是电路元件中最基础的两个部分之一。通过上面的试验,我们知道了与非门的性质。请确保你理解了它的性质。</p><p class="ql-block">与非门的性质:两端输入均为绿,则输出红,否则输出绿。</p><p class="ql-block"><b>非门(NOT)</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关要我们构造一个非门。通过观察下方真值表,我们可以看出:非门就是把输入结果取反,然后再输出。输入红就输出绿,输入绿就输出红。</p> <p class="ql-block">我们使用上一关的与非门,如此连接。</p> <p class="ql-block">本关最终答案</p> <p class="ql-block">我们可以看到,当输入端输入绿色,与非门的两端就都是绿色。根据与非门的性质“当两路输入均为绿色则输出红色”,也就做到了反转。那么如果输入端输出的是红色,与非门的两端就都是红色。根据与非门的性质“其余情况全部输出绿色”,此时输出的就会是绿色,也做到了反转。</p><p class="ql-block"><b>非门(N)</b></p><p class="ql-block">这关我们搭建的整个电路,放在一起,叫做“非门”,这是我们学习的第二个逻辑门。</p><p class="ql-block">非门的性质:将输入的结果取反。</p><p class="ql-block"><b>与门(AND)</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关要我们构造一个与门。通过观察下方真值表,我们可以看出与门的性质:当两端输入都是绿,就输出绿(其余情况都输出红)。</p> <p class="ql-block">我们如此搭建:</p> <p class="ql-block">与非门(NAND)的性质我们已经讲过两次:两端都是绿,输出红。</p><p class="ql-block">我们再来看一下与门的性质:两端都是绿,输出绿。</p><p class="ql-block">我们可以发现,与非门和与门在判断条件上是一样的,而输出的结果刚好相反。我们可以看一下上方真值表,其实“预期输出”和“当前输出”也是刚好相反。那么我们就可以在电路上加一个非门,将结果反转。</p> <p class="ql-block">本关最终答案</p> <p class="ql-block"><b>与门(AND)</b></p><p class="ql-block">这关我的搭建的整个电路,放在一起,叫做“与门”,这是我们学习的第三个逻辑门。</p><p class="ql-block">与门的性质:两端输入都是绿,则输出绿,否则输出红。</p><p class="ql-block">名称构成</p><p class="ql-block">我们已经学习了与门和与非门,我们发现它门之间其实只差一个字。其实 与非门 就是在 与门 的基础上再加一个 非门 ,可以简单理解为 与门+非门=与非门。</p><p class="ql-block">在这关中,我们应用的是 与非门+非门=与门,两个非“抵消了”。</p><p class="ql-block">通过这一点我们可以学习某些逻辑门名称的构成方式,其实这些名称很浅显易懂,之后有些逻辑门也是使用这种方法命名。</p><p class="ql-block"><b>或门(OR)</b></p><p class="ql-block"><b>关卡解析</b></p> <p class="ql-block">这关的要求是做一个或门。观察上方真值表,我们可以得知或门的性质:只要有一个绿,就输出绿。</p> <p class="ql-block">本关最终答案</p><p class="ql-block">我们在与非门的基础上,使用非门将输入反转,就会得到或门。这是为什么呢?</p><p class="ql-block"><b>德·摩根定律</b></p><p class="ql-block">我来用通俗的语言来解释一下这个定律:</p><p class="ql-block">1、如果对输入取反(也就是在电路左侧加非门),结果就会左右对称。</p><p class="ql-block">2、如果对输出取反(也就是在电路右侧加非门),每个结果会分别取反。</p><p class="ql-block">来举个例子,我们在上面将与非门的左侧加上非门,根据德·摩根定律的第一条,即对输入取反,我们观察NAND和OR的真值表,可以发现它们的输出确实是左右翻转的对称关系。我们在这关中能从与非门(NAND)获得或门(OR),正是应用了德·摩根定律。</p><p class="ql-block">请确保你理解了德·摩根定律。</p> <p class="ql-block"><b>或门(OR)</b></p><p class="ql-block">在这一关中我们获得了或门。</p><p class="ql-block">或门的性质:只要有一个为绿,就输出绿。</p><p class="ql-block"><b>基础逻辑</b></p><p class="ql-block">我们学习过了 与、或、非 这三个逻辑门,它们是最常用最重要的逻辑门。让我们来复习一下:</p><p class="ql-block">●与门:都是绿,输出绿。</p><p class="ql-block">●或门:只要有一个为绿,输出绿。</p><p class="ql-block">●非门:对输入取反。</p><p class="ql-block"><b>或非门(NOR)</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">如果你还没有学习过德·摩根定律,请先学习(在目录里查看)。</p><p class="ql-block">让我们再次请出德·摩根,帮助我们分析。</p> <p class="ql-block">这关我们的材料有与非门(NAND)和非门(N),我们需要得到的是或非门(NOR),我们观察德·摩根定律,发现NAND和NOR是对角的关系(NAND在左下角,NOR在右上角)。那么我们如果想要从NAND获得NOR,其实就简单了,只需要“既对输入取反,又对输出取反”,即在电路的两侧都加上非门。</p> <p class="ql-block">本关最终答案</p> <p class="ql-block"><b>或非门(NOR)</b></p><p class="ql-block">或非门的性质:两个都是红,就是绿。</p><p class="ql-block">我们已经学习过了 与非门(NAND)和或非门(NOR),在现实的电路中,这两个逻辑门是电路中最基础的组成部分。</p><p class="ql-block">如果你只是想要玩这个游戏,目前为止你并不需要去刻意的记住 与、或、非 三个逻辑门之外的其他逻辑门的性质,只需要理解。以后多使用,熟悉,用的时候再查看即可。</p><p class="ql-block"><b>高电平</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关要求我们制造一个不管怎样都输出绿色的电路。我认为应该有多种解决方式,这是我的方法:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">两条路,A没有非门,B有非门。这样,当输入是绿色,A就是绿色,当时如是红色,B就是绿色,保证了总有一条路是绿色的。在后面加入一个或门,根据或门的性质,只要有一个是绿,就是绿,就可以保证结果一定是绿。</p><p class="ql-block"><b>高低电平</b></p><p class="ql-block">高电平(ON)会作为电子元件加入我们的背包,它是我们接触的第一个没有输入端只有输出端的元件,也就是说它不需要接收任何数据,它不管怎样都会一直输出绿色。</p><p class="ql-block">于此同时,低电平(OFF)也会加入,它也没有输入端,不管怎样都会一直输出红色。</p> <p class="ql-block"><b>第二刻</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关主要是教会我们一种新的思路,反向思考问题。要求我们只在第二刻输出绿。</p> <p class="ql-block">我们观察第二刻,发现这道题其实是这样的:“只有当输入1是绿,且输入2是红时,输出绿,否则输出红。”据此,我做出了这样的电路:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">其实这里的思路有点像编程里的判断:</p><p class="ql-block">if A==True and B==False:</p><p class="ql-block">return(True)</p><p class="ql-block">else:</p><p class="ql-block">return(False)</p><p class="ql-block">我们放置与门,可以理解为“只有当两个条件都满足时,才输出绿”,接下来我们要做的就是“设定条件”。当A为绿,与门的上方就为绿。当B为红,则C为绿,则与门的下方也为绿。这种情况下就会输出绿,否则输出红,完成了我们这关的电路。</p><p class="ql-block">我们学习了一种新的思路,即从输出向输入推理,先设定“判断方式”,再设定“条件”。</p><p class="ql-block"><b>异或门(XOR)</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关的难度有所提高,要求我们制造出异或门(XOR),我们观察真值表:</p> <p class="ql-block">结合真值表和“异或门”这个名字,我们可以得知异或门的性质:如果两个输入不一样,就输出绿色。这也就是为什么名字里有“异”这个字。我们来思考一下,如果想让两个输入不一样,那么就至少得有一个绿色,所以我们先用或门来进行判断是否至少有一个是绿色。</p> <p class="ql-block">我们发现只有第四刻是错误的,我们需要排除两个都是绿这种情况。我们在输出2上增加一条支路,在上面加入了一个非门,并且对此结果和或门产生的结果进行一个与门判断,就变成了“输入1和输入2至少一个为绿,并且输入2不是绿时,输出绿”。</p> <p class="ql-block">在这种情况下运行,我们发现第四刻被修复了,但是第三刻又出了问题。“输入1和输入2至少一个为绿,并且输入2不是绿时,输出绿”其实是不全面的,我们还需要一个逻辑:“输入1和输入2至少一个为绿,并且输入1不是绿时,输出也是绿”,这样才能确保第三刻的情况也被考虑到。</p><p class="ql-block">到这里,我认为此题其实有不止一种解题方式,但是我只找到一种——将电路翻一倍。</p> <p class="ql-block">我们把原来的电路上下翻转一下,得到一个新的电路,此电路可以判断“输入1和输入2至少一个为绿,并且输入1不是绿时,输出也是绿”,然后我们将两个电路合起来,再用一个或门连接:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">这就是我们这关最终的电路,也就是异或门。</p><p class="ql-block"><b>异或门(XOR)</b></p><p class="ql-block">异或门的性质:当输入不同,输出绿。</p><p class="ql-block"><b>三路或门</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">接下来的两关比较简单,三路或门,顾名思义就是有三个输入端的或门。它的性质和或门是一样的:“只要有一个是绿,就输出绿”</p><p class="ql-block">我们先判断其中两个是否有绿色,获得的结果再和第三个判断是否有绿色,即可。</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>三路与门</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">三路与门,顾名思义就是有三个输入端的与门。它的性质和与门类似:“三个都是绿,就输出绿”。其实我们只要把上一关的或门换成与门即可。先判断输入1和输入2,判断的结果在和输入3做判断。</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>同或门(XNOR)</b></p><p class="ql-block">这是我们第一章:基础逻辑电路的最后一关。</p><p class="ql-block">同或门的性质:输入不一样,就输出红。</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关的关卡目标给了我们很明显的提示,“搭建一个和异或门输出相反的逻辑门,即同或门(XNOR)”,这意味着我们可以完完全全从逻辑门的名字出发。“异或门”和“同或门”这两个词语唯一和差别是“异”和“同”,我们只需要将异或门加上一个非门即可将“异”变为“同”。</p><p class="ql-block">其实本关也可以从另一个思考角度出发,即德·摩根定律。如果想把输出结果取反,需要在电路的右侧加非门。</p> <p class="ql-block">本关最终答案</p> <p class="ql-block"><b>第二章:算术运算和存储器</b></p><p class="ql-block"><b>前言</b></p><p class="ql-block">我们进入了第二章:算术运算和存储器。在第二章中,我们将会有两条支路,我们要研究算术运算和存储器,最后会制作出逻辑引擎、“小盒子”、计数器等。</p><p class="ql-block"><b>二进制速算</b></p><p class="ql-block">在开始之前,我们先复习一下学过的逻辑门:</p> <p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这一关和其他关卡不太一样,它更像是一个小游戏。你需要在玩这个小游戏的过程中,理解二进制的几个特点。这个小游戏并不难,你可以先自己玩,再听我来解析。具体玩法就是用下面的数字拼出来他给的数字。</p> <p class="ql-block">这关貌似有个BUG,它说必须通关3级,实际上必须把5级都玩完。</p><p class="ql-block"><b>二进制</b></p><p class="ql-block">我们生活中有很多种进制,例如最常用的十进制,表达色彩用的十六进制,表达时间用的六十进制,计算机底层使用的二进制等等。我们先来说说进制是什么。</p><p class="ql-block">从十进制说起,顾名思义就是逢10进1,例如:0-1-2-3-4-5-6-7-8-9,这时候就不能继续数了,要进1位,即:10-11-12-13-... 。我们可以看出,在十进制中,其实是没有“十”这个数字的,所谓的“10”,其实只是进了一位,是由“1”和“0”拼起来的。</p><p class="ql-block">我们再看看十六进制,十六进制在数到9之后是可以不进位继续数的,例如:0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F,数到F就不能继续数了,需要进行进位,即:A1-A2-A3-A4-...,接下来一直数到FF,就需要再进位一次,变成:AA1-AA2-... 。</p><p class="ql-block">也就是说,是几进制,这个数字就不存在,数到这个数字的前一位就不能数了。如果要继续往下数,就得进位。</p><p class="ql-block">现在我们再来看二进制,2-1=1,也就是说,二进制在数到1的时候就不能往下数了,必须要进位。所以,它是这样数数的:0-1-10-11-100-101-110-111-1000-... 。二进制就是即逢2进1,2不存在,是由“1”和“0”拼起来的。请确保你理解了二进制是什么。</p><p class="ql-block"><b>位权</b></p><p class="ql-block">说了这么多,这个关卡到底需要我们明白什么?我们还需要引入新的概念——位权。</p><p class="ql-block"><span style="font-size: 22px;">位权=基数</span>位数-1</p><p class="ql-block">其中,几进制基数就是几。在二进制中,可以这样书写:</p><p class="ql-block"><span style="font-size: 22px;">位权=2</span>位数-1</p><p class="ql-block">假设我们现在有一个8位的二进制数10101010,那么根据公式计算,可得它每一位的位权分别是:128、64、32、16、8、4、2、1。你有没有发现,这和本关下方的按钮是一样的?</p> <p class="ql-block">现在,我来举几个例子,你对照上图,就能发现其中的奥妙:</p><p class="ql-block">二进制100转化为十进制是多少?是4</p><p class="ql-block">二进制10000转化为十进制是多少?是16</p><p class="ql-block">二进制10100转化为十进制是多少?是4+16=20</p><p class="ql-block">还不懂?我再举几个:</p><p class="ql-block">二进制10转化为十进制是多少?是2</p><p class="ql-block">二进制111000转化为十进制是多少?是32+16+8=56</p><p class="ql-block">二进制10010101转化为十进制是多少?是128+16+4+1=149</p><p class="ql-block">二进制11111111转化为十进制是多少?是128+64+32+16+8+4+2+1=255</p><p class="ql-block">明白了吗?这对进制转换有很大的帮助。现在你可以尝试以这种思路,再次游玩本关卡。</p><p class="ql-block"><b>成对的麻烦</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们输入已经拓展到了4个。现在来观察真值表,找到规律。</p> <p class="ql-block">规律就是:“当有≥2个绿,输出绿”这关的解决方法也比较简单。首先把四个输入端两两接入与门检测,根据我们小学就学过的排列组合,4个输入端的排列方式有:</p><p class="ql-block">(1,2), (1,3), (1,4),</p><p class="ql-block">(2,3), (2,4),</p><p class="ql-block">(3,4)</p><p class="ql-block">共6种组合方式,因此我们需要用到6个与门:</p> <p class="ql-block">将它门按照我们策划过的排列组合进行连接:</p> <p class="ql-block">然后将这些结果使用或门连接,我们可以使用2个三路或门+1个或门:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">这样就完成了,但是不知道有没有更好的方法。</p><p class="ql-block"><b>奇数个信号</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关要求我们使用3个元件,实现“输入绿为奇数个,就输出绿”。</p><p class="ql-block">首先我们要先看到问题的本质,假设我们现在只有两个输入端口,那么我们如果想判断是否是奇数个为绿,其实我们判断的就是这两个输入是不是一个绿一个红。那么什么逻辑门是能解决这个问题的呢?是异或门。</p> <p class="ql-block">这种情况下,“判断输入是否不同”==“判断绿色是不是奇数个”。当我们的输入数拓展到4个,其实问题也是如此。我们只需要先判断两个,然后判断后两个,再把这两个判断结果放在一起判断即可。</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>循环依赖</b></p><p class="ql-block"><b>循环依赖</b></p><p class="ql-block">循环依赖是指一个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成一个环形调用,有下面 3 种方式。</p> <p class="ql-block">在本游戏中,至少目前,循环依赖是被禁止的。在某些电路中,循环依赖是被允许的。目前你不需要知道哪些电路是被允许的。</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们构建一个受自身影响的电路即可。也就是说,一个元件的输出连接到自身的输入上,例如:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">其实此结构也可以满足测试2的要求:</p> <p class="ql-block"><b>信号计数</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">如果你还没有学习二进制相关知识,可以在目录里查找学习。</p><p class="ql-block">本关较为复杂,用到了很多之前的知识,我们需要一点点思考,解决问题。</p><p class="ql-block">请务必先理解本关的目标:</p> <p class="ql-block">我们的输出端一共有3个引脚,分别是1、2、4。这3个引脚是怎么运作的呢?是这样的:</p><p class="ql-block">第一个被点亮了结果就+1</p><p class="ql-block">第二个被点亮了结果就+2</p><p class="ql-block">第三个被点亮了结果就+4</p><p class="ql-block">也就是说:</p><p class="ql-block">输入端亮了1个→让输出端的第一个亮</p><p class="ql-block">输入端亮了2个→让输出端的第二个亮</p><p class="ql-block">输入端亮了4个→让输出端的第三个亮</p><p class="ql-block">也许你会问:“那如果亮了三个,该怎么办?”,其实这就是我们这关需要解决的最大问题。我们不妨先把前三种情况做出来,先忘掉亮了三个这种情况。</p><p class="ql-block">先解决第一个:如何判断输入端是否有1个绿?因为输入端有几个绿只有四种情况,即1个、2个、3个、4个。而且“3个”这种情况先被我们刨除在外了,就只剩下1个、2个、4个这三种情况。在剩下的三种情况中,显然只有“1个”是奇数,而“2个”和“4个”都是偶数,所以“1个”是最好确定的。</p><p class="ql-block">还记得我们之前有一关叫什么名字吗?“奇数个信号”,我们是学习过如何判断奇数个信号的:</p><p class="ql-block">这种情况下,“判断输入是否不同”==“判断绿色是不是奇数个”</p><p class="ql-block">我们可以直接沿用“奇数个信号”的电路:</p> <p class="ql-block">观察真值表,我们可以发现,所有预期输出1的地方,全都正确了。</p><p class="ql-block">现在我们来考虑:如何判断输入端是否有2个绿?我们好好回忆一下,其实我们做过类似的电路。记不记得我们做过一个电路:“如果≥2个绿,则输出绿”?没错,是在“成对的麻烦”那关。现在我们只要把电路改成:“如果≥2个绿,且不是4个绿,则输出到第2个端口”即可。</p><p class="ql-block">现在我们来回忆一下:如果想判断是不是有两个是绿,只需要成对进行与门判断,然后再用或门连接即可。我们将这个电路做出来:</p> <p class="ql-block">然后,我们将刚才做的两个电路,结合一下。注意,该插在哪个孔的还要插在哪个孔。</p> <p class="ql-block">运行后发现,我们不仅解决了2的问题,还解决了我们刨除掉的3的问题,这是为什么?很简单,因为1+2=3,这用到了我们之前的进制转换原理。我们做好了1的电路,2的电路,当这两个电路叠加在一起,自然就是3的电路。</p><p class="ql-block">现在,我们只差4的电路,我们只要检测四个输入端口是否全是绿色即可,这很简单。先两两判断,然后再总的判断:</p> <p class="ql-block">接下来,我们将3个电路合在一起。注意,该插在哪个孔的还要插在哪个孔。</p> <p class="ql-block">运行后发现,还是不能准确的判断4的结果,显示为6。分析,错误源于“当同时出现4个绿色时,必然同时出现2个绿色”,因此,4+2=6。我们需要想办法做到“当同时出现4个绿色时,使2的电路失效”。我们只需要在2路和3路上加一个异或门,也就是“在2路和3路中,只有1个输出绿色时,才能在2路输出绿色”,可以理解为“只有在3路关闭时,2路才能启用”。这就是本关的完整电路:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>题外话</b></p><p class="ql-block">给大家看看我在没有好好分析的情况下硬造的版本,奇迹的是它能够满足要求!这里奉劝大家,在拓展思维发散创意的同时,也要先理解题目的含义,搞清楚需要运用到哪些知识点。</p> <p class="ql-block"><b>半加器</b></p><p class="ql-block"><b>布尔值</b></p><p class="ql-block">从本关开始的大部分关卡,我们很有可能把红色叫做0,把绿色叫做1。</p><p class="ql-block">布尔值是“真(True)”或“假(False)”中的一个。</p><p class="ql-block">你可以简单的这样理解“布尔值”:</p><p class="ql-block">真 == True == 1 == 绿</p><p class="ql-block">假 == False == 0 == 红</p><p class="ql-block">当我们在说“1”和“绿”时,其实我们说的是同一个东西。</p> <p class="ql-block">如果你还不理解什么是布尔值,请点击这里跳转到百度百科查看,不用了解的太深入。</p><p class="ql-block"><b>总和、进位</b></p><p class="ql-block">我们在学习二进制时学习过:</p><p class="ql-block">总和(SUM)</p><p class="ql-block">进位(CAR)</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们有两个输入端,两个输出端,但本关比较简单。先观察:</p> <p class="ql-block">可以分析出这关要让我们做什么:</p><p class="ql-block">A:若都是0,输出0</p><p class="ql-block">B:若有且只有1个1,在总和输出1</p><p class="ql-block">C:若有2个1,在进位输出1</p><p class="ql-block">首先我们发现,如果只看A和B,可以总结为“如果输入不同,就在总和输出1”,这显然是异或门的性质,因此我们先这样接入一个异或门:</p> <p class="ql-block">接下来,然后来看C,我们只需要在两个输入同时为1时,输出到进位即可:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>半加器</b></p><p class="ql-block">我们本关中做出的电路,整体来看,叫做半加器。半加器是指对两个输入数据位相加,输出一个结果位(SUM)和进位(CAR),没有进位输入的加法器电路。</p><p class="ql-block"><b>延迟线</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">这关获得了延迟线,可以把数据延迟一刻再输出到下一段电路。目标是延迟两刻,其实只要在一条线里加两个延迟线即可:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>加倍</b></p><p class="ql-block"><b>字节</b></p><p class="ql-block">字节,单位比特(bit),1bit=1个8位数据=8个1位数据。</p><p class="ql-block">你可以简单的这样认为:1个8位数据=1个8位的二进制数</p><p class="ql-block"><b>8位分线器、8位集线器</b></p><p class="ql-block">本关我们获得了8位分线器、8位集线器这两个元件。</p><p class="ql-block">8位分线器:将1个8位数据拆解为8个1位数据</p><p class="ql-block">8位集线器:将8个1位数据集合为1个8位数据</p> <p class="ql-block">举个例子:</p> <p class="ql-block">根据我们之前讲过的十进制转二进制,8位分线器把90这个数字拆解为2、8、16、64,那么这4个数字就是绿色,其他数字就是红色。八位集线器会把这些数字再合到一起,再变成90。</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关我们要制作一个将数字翻倍的电路。其实非常简单,只要把每个1位数据都×2即可。本来应该接2的咱们接4,本来应该接4的咱们接8,每个都翻倍,数据就翻倍了。</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>全加器</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关几乎和“信号计数”那关的1、2、3完全一样,只是把红、绿换成了0、1。</p> <p class="ql-block">本关和半加器类似,只不过输入变成了三个。我们观察表格,找规律,得出要求:</p><p class="ql-block">没有1 不输出1</p><p class="ql-block">1个1 在总和输出1</p><p class="ql-block">2个1 在进位输出1</p><p class="ql-block">3个1 在总和和进位都输出1</p><p class="ql-block">这四种情况其实分别对应二进制里的 0、1、10、11 。</p><p class="ql-block">首先,第二条要求可以直接照搬我们做过好几次的电路,还记得吗?</p><p class="ql-block">某些情况下,“判断输入是否不同”==“判断1是不是奇数个”</p> <p class="ql-block">2号要求处理完毕,现在我们处理3号要求。根据我们在“信号计数”那关的经验,当我们做好3号要求时,4号要求应该会自动做好,因为4号要求其实是2号要求和3号要求的叠加。</p><p class="ql-block">如何判断是否有2个1,我们也学过。两两进行与门判断,然后再用或门连接:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">我们发现,要求4真的自动做好了。这就是本关的电路。</p><p class="ql-block"><b>奇变偶不变</b></p><p class="ql-block"><b>循环依赖白名单</b></p><p class="ql-block">我们之前学习过,在本游戏中,循环依赖是不被允许的。但是延迟线的加入可以解决这个问题。</p> <p class="ql-block">游戏中的方形引脚,不会造成循环依赖,因为它不会影响同一刻的输出值。</p> <p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关要求我们制作一个“再偶数刻输出0,在奇数刻输出1”的电路。</p> <p class="ql-block">观察真值表发现,本关的输入全是0,因此最终结果与输入毫无关系,所以实际上我们可以直接将输入端抛弃,这是一个障眼法。我们可以这样制作:</p> <p class="ql-block">本关最终答案</p><p class="ql-block">现在我们一刻一刻来看这个循环:</p><p class="ql-block">第0刻:黄色线灭,绿色线亮。延迟线存储了信号,将在下一刻放出</p><p class="ql-block">第1刻:延迟线存储的信号被放出,黄色线亮,绿色线因为非门灭掉</p><p class="ql-block">第2刻:同第1刻...</p><p class="ql-block"><b>1位开关</b></p><p class="ql-block"><b>开关(S)</b></p><p class="ql-block">只有当上方被激活时,右方才能有反应,否则无论左侧输输入什么,输出都是0。</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关我们要制作一个异或门(XOR),也就是当两边不一样就输出1。但是我们的材料有限,只能用2个非门和2个开关。我们将1加上非门作为开关,2作为通向输出的线路:</p> <p class="ql-block">这时我们会发现:</p><p class="ql-block">当1开启时,输出一定为0</p><p class="ql-block">当1关闭时,输出2直接影响输出结果</p><p class="ql-block">此时我们还差两种被遗漏了,也就是:</p><p class="ql-block">当2开启时,输出一定为0</p><p class="ql-block">当2关闭时,输出1直接影响输出结果</p><p class="ql-block">这样才是一个完整的异或门。我们需要将这个电路翻倍,也就是将1加上非门作为开关,2作为通向输出的线路:</p> <p class="ql-block">然后将两个电路拼在一起,注意不要插错孔:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>短路处理</b></p><p class="ql-block">我们仔细看一下这个电路的最右侧。在我们之前的关卡中,如果这样连接会显示短路,但是本关并不会。请仔细阅读本关关卡说明第一页,弄清楚这是为什么!</p> <p class="ql-block"><b>1位取反器</b></p><p class="ql-block">观察</p> <p class="ql-block">观察本关背景,我们可以看到有很多水滴型的图案,它们由分型构成。而分型,就意味着无限。因此,本关背景所暗示的是“无限”。它们就像是一朵朵绽放的花朵,象征着无限的生命力。它们又像是一个个的灵魂,象征着死亡。本关,是生命与死亡的无限碰撞,是矛盾的产生与矛盾的化解,是无限复杂的宇宙,而无限与本关毫无关联,实际上这个背景图也与本关毫无关联(⊙x⊙;)</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">让我们来看一眼真值表:</p> <p class="ql-block">怎么这么眼熟?这不就是异或门吗?!恭喜过关。</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>1位取反器</b></p><p class="ql-block">通过本关我们得知,背景可以深刻的影响人类认知(不是</p><p class="ql-block">异或门其实也可以被当作一个取反器,你可以把它理解成是一个可以开启或关闭的非门。你可以把一端作为要输出的数据,那么另一端就可以用于去决定是否要取反。</p><p class="ql-block"><b>8位或</b></p><p class="ql-block"><b>按位或运算</b></p><p class="ql-block">按位或运算符是双目运算符。其功能是参与运算的两数各对应的二进位相或。</p><p class="ql-block">法则:只要对应的2个二进位有一个为1时,结果位就为1 。</p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">理解了按位或运算的意思,本关就很简单了。按照 按位或运算 法则,我们将2个8位八位线,拆成16个1位线。把对应的位进行 逻辑或运算 然后再放入集线器。</p> <p class="ql-block">以上是用1举个例子,接下来把剩下的14个都像这样操作:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>8位非</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关异常简单,解题方法就写在下面。</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>8位非</b></p><p class="ql-block">性质:运算前+运算后=255 ,举个例子:</p> <p class="ql-block">28+227=255</p><p class="ql-block">反码</p><p class="ql-block">把一个二进制数的每位都反转,例如 10101010 和 01010101 互为反码。其实这一关就是在获取一个二进制数的反码,这种方式我们以后还会用到。</p><p class="ql-block"><b>8位加法器</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们先将输入的2个8位数据拆分为16个1位数据,然后将他们放入全加器进行相加操作,再输出至集线器:</p> <p class="ql-block">这样我们就解决了第0位,现在我们要解决第1位。根据我们之前讲过的二进制原理,分线器上2个写着“2”的输入端,实际上是写着“1”的位的进位。那么下面这三张图是,画红圈的三个点,实际上应该是在同一位上的:</p> <p class="ql-block">请确保你理解了。</p><p class="ql-block">所以说,我们只要把这三个同位的点加起来,再输出到集线器的“2”即可:</p> <p class="ql-block">接下来,三个画黄圈的点,就又是在一位上的了。我们就一直这样制作下去,一直做到不能再做,我们一共需要8个全加器:</p> <p class="ql-block">最后一个全加器右下角的点又是一个进位,是第九位,超出了8位数据,我们只要把它连到CAR上就好:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>8位加法器</b></p><p class="ql-block">我们本关的整个电路构成了一个8位加法器,它可以对输入的两个数据求和。</p><p class="ql-block"><b>负数</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">在本关中你会学习使用补码表示法表示负数。本关又是类似小游戏,玩着玩着你就能发现所有奥妙。</p><p class="ql-block">在已经学习过二进制的前提下,本关不需要在过多做解释,注意关卡结束时的要点总结即可:</p> <p class="ql-block"><b>补码</b></p><p class="ql-block">把一个二进制数的反码+1就是补码,例如 10101010 的反码是 01010101,再把 01010101+1 得 1010110。1010110就是10101010的补码。</p><p class="ql-block"><b>相反数</b></p><p class="ql-block">一个二进制数的相反数其实就是它的补码。例如,10101010的相反数是1010110。</p><p class="ql-block"><b>数据选择器</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">分析本关问题,可以得出是需要我们制作一个这样的电路:</p><p class="ql-block">选通器为红,将A路输出</p><p class="ql-block">选通器为绿,将B路输出</p><p class="ql-block">首先我们在选通器上做两条路,这两条路相反,不是A亮就是B亮:</p> <p class="ql-block">然后放置开关,注意必须要放8位开关:</p> <p class="ql-block">连接即可,注意不要弄错A和B:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>相反数</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们倒着来推:</p><p class="ql-block">1、如何获取相反数?我们在“负数”里讲过:“一个二进制数的相反数其实就是它的补码”</p><p class="ql-block">2、如何获取补码?我们在“负数”里讲过:“把一个二进制数的反码+1就是补码”</p><p class="ql-block">3、如何获取反码?我们在“8位非”里讲过:“把一个二进制数的每位都反转就是反码”</p><p class="ql-block">因此,我们首先把每一位都反转,获取反码:</p> <p class="ql-block">然后,我们只要将这个反码+1,就是补码,而补码就是它的相反数。</p><p class="ql-block">胜利在望了!可是如何获取1呢?我们在“半加器”里讲过:</p><p class="ql-block">真 == True == 1 == 绿</p><p class="ql-block">也就是说,我们只要使用“高电平”元件,当作1即可。使用8位加法器,将刚才获得的反码,与高电平的1进行相加,即可获得补码,也就是相反数:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>题外话</b></p><p class="ql-block">之前还行,玩到这突然感觉这个游戏门槛并不低。光是玩这一关,我读各种资料就至少读了一个半小时,最后搭建只花了一分多钟。我感觉如果不知道“一个二进制的相反数其实就是它的补码”这个原理,估计想破脑袋也想不出来......</p><p class="ql-block"><b>总线</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们将4条蓝线汇集到一条上,这条线叫做“总线”。总线的左侧,我们通过两个8位开关,控制应该让哪个数据保持在总线上。总线的右侧,我们通过两个8位开关,控制数据会进入哪个输出端。</p> <p class="ql-block">接下来做的都是以前做过的。每个1位输入端控制两个开关,并且一次只能有一个开关开启,因此我们每组里添加一个非门保证始终一开一闭,注意不要连错:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>优雅存储</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关要求我们制作一个存储器,存储器会一直存储数据,直到写入端要求它更新。</p><p class="ql-block">留存数据无疑需要使用延迟线,但是延迟线只能保存一刻数据,所以我们要一直刷新它。我们先构成一个循环,延迟线会一直存储数据,直到它被关闭,如下图:</p> <p class="ql-block">我们需要一个开关来控制它何时被关闭:</p> <p class="ql-block">新增的线是蓝色的。</p><p class="ql-block">当然这个开关现在起不到任何作用,我们需要把延迟线的输出值输入到开关上:</p> <p class="ql-block">然后我们将待写入的值接入总线:</p> <p class="ql-block">然后用一个开关来控制:</p> <p class="ql-block">本关最终答案按</p><p class="ql-block"><b>1位存储器</b></p><p class="ql-block">在本关中我们做出的电路是1位存储器,它可以储存1位数据。</p><p class="ql-block"><b>存储一字节</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">我们先制作一个可以存储8位数据的存储器。我们只有1位存储器,所以我们需要8个。将8位数据拆成8个1位数据,存储到8个存储器中:</p> <p class="ql-block">当然,我们还需要制作输出端,将存储的8个1位数据再转化为1个8位数据:</p> <p class="ql-block">接下来就是如何控制,它有3个要求:</p><p class="ql-block">输入0亮:读取并输出</p><p class="ql-block">输入1亮:写入到存储器</p><p class="ql-block">输入0亮:启用输入端</p><p class="ql-block">我们先制作第二个。只要将输入1连接到每个1位存储器即可:</p> <p class="ql-block">此时,将输入0连接至输出端下方即可完成一和三:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>8位存储器</b></p><p class="ql-block">我们本关制作出的整个电路是8位存储器,可以存储1字节的数据。</p><p class="ql-block"><b>1位解码器</b></p><p class="ql-block"><b>关卡解析</b></p><p class="ql-block">本关的电路搭建特别简单,不需要过多解释,直接看图即可:</p> <p class="ql-block">本关最终答案</p><p class="ql-block"><b>1位解码器</b></p><p class="ql-block">本元件就相当于上面的电路,可以在两路输出中选择一路。</p>