玛雅数字

玛雅数字

来自 MicroBlocks

Boards
主板:

micro:bit

Component/s
配件:

无需配件

翻译:自在飞叶

介绍

玛雅文明使用两种不同的数字表示形式。其中一种使用非常精致和华丽的神像描绘来代表数字,人们有在石刻,壁画和手稿中发现这种表示形式。

Engraved ornamental Maya numerals
Engraved ornamental Maya numerals in Copán, Honduras - CC-BY-2.0 Adalberto Hernandez Vega

第二种数字表示形式是日常活动中常用的表示形式,仅由点和线组成,外加数字0的特殊表示形式。这是我们将在本次活动中探索的表示形式。

Written Maya numerals

玛雅数字系统使用二十个数码。也就是说,与我们平常使用十个数码(0 到 9)不同,玛雅数字用20个符号来表示0到19的数字。

让我们看一下这些数字:

The Maya Digits

上图左上角的第一个数字表示零。它的右边依次是数字从1,2,3,4。在4之后,用一条横杠来表示数字5(图中第二行开头),然后不断向其添加点以表示6、7、8和9(图中第二行右侧的数字)。

两条横杠表示两个5,即10。 同样,三条横杠代表15。 在此基础上,继续添加点,直到有三条横杠和四个点,加起来是19,即20以内最大的数字。

所需材料

对于这个活动,你只需要一个micro:bit,尽管有两个micro:bit可以让你显示20以上的数字。

过程

我们将编写一个MicroBlocks程序,该程序使用micro:bit 5x5 LED显示屏来表示Maya数字。显示屏最上面一行将显示玛雅数字的点,而最下面的三行将显示横杠。例如,下图显示的数字是17。

Number 17 represented in the micro:bit 5x5 LED display

显示数字0

我们将新建一块名为“绘制Maya数字”的积木。使用这块积木的话,要传入小于20的十进制数,而后在5x5 LED显示屏上输出其Maya表示形式。

要做到这些,选择“我的积木”类别,然后单击“新建命令积木”按钮。将新积木命名为“绘制Maya数字”,然后单击确定。

新建绘制Maya数字积木

这会将积木定义添加到脚本区域:

"绘制Maya数字"积木的初始样子

由于使用该积木时需要传入将被显示的数字,我们需要单击其名称旁边的向右小箭头以添加参数。默认情况下,新参数将被命名为 foo。不过,我们可以在foo身上单击,在弹出的小窗口里头将其重命名为其它名称。如下图所示,我们把foo重命名为“数值”,例如:

设置“绘制Maya数字”积木的参数

看一眼前面的Maya数字表格,我们注意到数字0(Maya digit zero)与任何其他数字都不同。虽然其他数字遵循逐渐添加横杠和点的模式,但数字0绝对是一种特例,于是“绘制Maya数字”积木要做的第一件事是判断提供的数字是否等于0,如果是,则用特别的做法来绘制它。

下面的积木显示数字0。

数字0的显示

"绘制Maya数字"积木的第一版如下所示:

只能绘制数字0

上图中,最下方的积木是使用“绘制Maya数字”积木来显示 数字0。点击这块积木,你会在micro:bit 5x5 led显示屏上看到Maya数字0的模样。这块积木的作用是测试"绘制Maya数字"积木的功能是否正确。

显示1到5之间的数字

介于 1 和 5 之间的数字在 Maya 数字中表示为点。我们将使用 micro:bit 5x5 led显示屏的最上面一行来显示各个点。

要做到这一点,我们可以使用“led显示”类别下的“点亮”积木。“点亮”积木需要两个参数:x和y,其中x代表列号,y代表行号。下图所示积木执行的话,将点亮led显示屏中第3行第3列的小灯泡。

点亮积木

当数字小于5时,我们要点亮的小灯数目等于数字的值。以数字为4为例,我们要点亮4个小灯。对此,我们可以使用的一个技巧是令x从1递增到4,分别点亮第一行x列的小灯。

于是,我们可以使用以下4块积木来做到显示数字4的事情:

显示数字4

我们可以用下面的for循环来实现上述逻辑:

用for循环显示数字4

至此,以4为例讲了如何显示1到5之间的数字。要显示1,2,3或者4的话,循环次数需要取决于要传给“绘制Maya数字”积木的数值参数。于是,我们需要添加一个分支来检查数值参数(记作v)是否小于5。如果v小于5,那么将在第一行点亮v个小灯。在“如果”积木底部的右向箭头上单击两次以添加另外两个分支。在小于5的分支下添加显示1到5之间的数字的积木,如下所示:

能显示0到4

现在可以使用下面的两块积木测试上述新修改的积木,看看能不能正确显示数字0,1,2,3或者4。两块积木中的“清除显示”积木的作用是避免下一次的显示效果与前一次的显示效果混合在一起。比如,我们想先测试显示Maya数字0,再测试显示Maya数字1。如果没有“清除显示”积木的话,无法正确显示Maya数字1。

清除显示并测试显示数字0-4

显示5到10之间的数字

对于 5 到 10 之间的数字,我们将重用刚刚编写的代码,此外加一条横杠。让我们再看一下玛雅数字的表示形式:

The Maya Digits

请注意,第二行数字与第一行数字非常相似,除了点数下方的横杠。让我们首先编写一些代码,在micro:bit 5x5 led显示屏的第三行中画一条横杠。

就像我们在前面使用for循环来点亮小灯一样,要在第三行上画一条横杠,我们可以循环五次,依次点亮第三行上的5个小灯,如下所示:

在第三行画横杠

单击上述脚本,可以看到5x5 LED显示屏的第三行的5个小灯都被点亮。

进一步地,我们可以再次扩展“绘制Maya数字”积木,见下:

绘制0到10之间的数字

如果您现在尝试显示数字 6,您将看到屏幕上出现一条横杠,但它缺少横杠上方的点。请记住,6表示为6

值得注意的是,对于5到10之间(不含10)的数字n,我们需要画一条横杠,而后在第一行中点亮n-5个小灯。以数字8为例,我们需要在第三行上画出一条横杠,并且在第一行点亮3个小灯。第三行上的横杠对应5,第一行内3个小灯对应8 - 5

既然前面写好的代码已经可以显示小于5的数字,我们可以调用“绘制Maya数字”积木来显示横杠上的点号。脚本如下:

显示1到10之间的数字

在积木定义中调用积木自身看起来很奇怪,但这实际上是编程中非常普遍的做法!

您现在可以测试扩展后的积木是否能够正确显示0到9之间的所有数字,下面的脚本可以做到这样的测试。

显示1到10之间的数字的测试

如果你测试了0到9之间的所有数字,你会发现无法正确显示数字5。下文将给出解决这个问题的办法。

显示10到19之间的数字

想要显示10到15之间的数字,我们能想出下面的代码:

显示0-15之间的数字

我们可以看到,显示5到10之间的数字的分支与显示10到15之间数字的分支很相似。两者的代码仅仅是“点亮”积木的y坐标不相同。前者的y坐标是3,后者的y坐标是4。

我们来观察一下各个数字。当一个数字大于4,显示这个数字就要加一条横杠。下表指出不同数字范围对应的横杠数量。

数字范围 横杠数量
0 到 4 0
5 到 9 1
10 到 14 2
15 到 19 3

可以看到,横杠的数量等于数字除以5之后的商。由于我们是在micro:bit 5x5 LED显示屏的第3行开始画横杠,所以横杠数量加上2,就是横杠的y坐标(也即行号)。比如,对于15到19之间的数字n,横杠数量是3,加上2,得到行号为5,也就是第5行画一条横杠。接下来,只需要处理显示n-5的问题。

画横杠

至此,显示0到19之间数字的代码如下:

显示0到19之间的数字

然而,当数字是5的倍数时,上述代码无法正确显示该数字。造成这个问题的原因是,最后一步总是会显示数字0,数字0的图案覆盖了前面的显示的内容。比如,显示数字10时,第一步画出第4行上的横杠,第二步画出第3行上的横杠,第三步也即最后一步显示数字0。数字0的图案覆盖了前两步画出的横杠。因此,当数字为5,10或者15的时候,我们需要避免“显示数字0”的步骤。

一个办法是在调用“绘制Maya数字”积木(参数为“数值 - 5”)之际,先判断“数值 - 5”是否大于0。下面的代码做到了这一点:

正确显示0-19之间的数字

现在,你可以对0到19之间的每个数字进行测试。这些数字都能正确显示。

Maya数字计数器

既然我们写好了“绘制Maya数字”积木,我们可以通过micro:bit的两个按钮对显示屏上的数字进行加一(+1)或者减一(-1)操作。

首先,我们选择“变量”积木类别,单击“新建一个变量”按钮,在弹出的小窗口内,把变量命名为“计数值”。这样,我们定义了名为“计数值”的变量。

定义变量

在程序启动的时候,我们把计数值设为0

计数值初始化为0

按下按钮B将增加计数值,显示屏上的Maya数字增加1,而按下按钮A将把计数值减1。

按下按钮*B*将增加计数值 按下按钮*A*将把计数值减1

多学一点:显示大于19的Maya数字

显然,一块micro:bit板子只能显示一个Maya数字。不过,假如你恰好还有一块micro:bit板子,那么你就可以显示第二个Maya数字,也就是说,你可以显示一个“两位数”,即两位Maya数字组成的数。

我们利用micro:bit的广播功能,让两块micro:bit板子进行通信,使得其中一块显示“两位数的个位”,另一块显示“两位数的十位”。此处,“十位”这个表述不太精确,但帮助理解。假设“两位数的十位”是2,意味着对应的十进制数是40;又假设“两位数的个位”是3,那么“两位数的十位”和“两位数的个位”合在一起,对应的十进制数是43。

首先,从积木库导入广播积木库(即积木类别)。做法是,单击“积木库”三个字右侧的+号,在弹出的窗口中选择“广播”条目,单击窗口右下角的“打开”按钮。接下来,你会在浏览器窗口的左侧看到“广播”积木类别。

对于显示大于19的数字这个任务,思路是,一旦显示个位的micro:bit板子的数字大于19,那么就向显示十位的micro:bit板子发送“进位”。比如,假设要显示十进制数20,那么显示个位的micro:bit板子向显示十位的micro:bit板子发送进位1。又比如,假设要显示十进制数42,那么显示个位的micro:bit板子向显示十位的micro:bit板子发送进位2。

按下按钮B,加1;数字大于20的话,进位

显示十位的micro:bit板子收到进位后,执行下面的脚本代码,在显示屏上显示表示十位的数字:

显示十位的板子收到进位

要注意的是,我们一定要启动上述脚本。启动脚本的做法有两种,第一种是单击脚本上的积木,第二种是单击Microblocks窗口右上角的绿色箭头。

显示十位的micro:bit板子可以正常工作,而显示个位的板子需要显示除以20得到的余数。也就是说,接收到广播消息的板子要显示十位,而对外广播消息的板子要显示个位。

下面的积木得到计数器除以20得到的余数。

除以20得到余数

实际上,我们能够简化上述脚本。做法是,不管要显示的数字是不是大于19,都要求显示个位的micro:bit板子向显示十位的板子发送进位。当要显示的数字小于20的时候,发送的进位是0。这使得十位显示为0,是对的。

简化版,按下按钮B,加1;数字大于20的话,进位

最后,我们要修改按下按钮A(使得计数值减1)时执行的脚本代码,把进位发送到显示十位的micro:bit板子:

按下按钮A,减1;广播进位

有了以上代码,我们能够显示最大为399的Maya数字。

思考题:你能否用三块或者更多块micro:bit板子来显示更大的数字?