本节最后修改于 2023 / 07 / 25
上节讲了与、非和或的实现,我们还知道世界上有与非、或非、异或和同或等逻辑,那么能不能在我的世界中通过与、非和或组合出这些呢?
# 例子
# 如果重工业玉米并非同时有熊孩子标签和tnt,也就是“有熊孩子标签”与非“背包有tnt”为真,提示“重工业玉米简直是风流倜傥英俊潇洒,人见人爱花见花开”
[~,~,~,~] clear @a[name=重工业玉米] tnt -1 0
[+,L,+,0] tag @a[name=重工业玉米,tag=熊孩子] add T_8 //得到A与B的标签
[+,L,-,0] execute @a[name=重工业玉米,tag=!T_8] ~~~ say 重工业玉米简直是风流倜傥英俊潇洒,人见人爱花见花开
[+,L,-,0] tag @a[tag=T_8] remove T_8
看起来我们就轻松地实现了与非。
# 例子
# 如果重工业玉米既没有熊孩子标签也没有tnt,也就是“有熊孩子标签”或非“背包有tnt”为真,提示“重工业玉米英俊的面庞在我心中挥之不去,如同静夜月光,照亮了我的心房”
[~,~,~,~] clear @a[name=重工业玉米] tnt -1 0
[+,L,+,0] tag @a[name=重工业玉米] add T_E //得到A或B的标签
[+,L,-,0] tag @a[name=重工业玉米,tag=熊孩子] add T_E //得到A或B的标签
[+,L,-,0] execute @a[name=重工业玉米,tag=!T_E] ~~~ say 重工业玉米英俊的面庞在我心中挥之不去,如同静夜月光,照亮了我的心房
[+,L,-,0] tag @a[tag=T_E] remove T_E
或非的实现也比较简单。
# 例子
# 如果重工业玉米熊孩子标签和tnt二者只有一个,也就是“有熊孩子标签”异或“背包有tnt”为真,提示“0.5秒与他的擦肩而过,我的脑海中便深深烙下了他的身影。不知为何,即便不去确认,我也心中了然:他就是重工业玉米了”
[~,~,~,~] clear @a[name=重工业玉米] tnt -1 0
[+,L,+,0] tag @a[name=重工业玉米] add T_E //得到A或B的标签
[+,L,-,0] tag @a[name=重工业玉米,tag=熊孩子] add T_E //得到A或B的标签
[+,L,-,0] clear @a[name=重工业玉米] tnt -1 0
[+,L,+,0] tag @a[name=重工业玉米,tag=熊孩子] add T_8 //得到A与B的标签
[+,L,-,0] tag @a[name=重工业玉米,tag=!T_8] add T_7 //得到非(A与B)的标签
[+,L,-,0] execute @a[name=重工业玉米,tag=T_E,tag=T_7] ~~~ say 0.5秒与他的擦肩而过,我的脑海中便深深烙下了他的身影。不知为何,即便不去确认,我也心中了然:他就是重工业玉米了
[+,L,-,0] tag @a[tag=T_E] remove T_E
[+,L,-,0] tag @a[tag=T_8] remove T_8
[+,L,-,0] tag @a[tag=T_7] remove T_7
这就是异或的实现。
发现在指令编写到一定程度时,有条件命令方块基本不会再出现了,我们会一直以选择器的形式进行条件运算。选择器一般的用法是标签。那么对于着繁多的标签和运算,怎么才能防止自己犯迷糊呢?可以使用表达式作为标签的名称,来表示含义,这样可以使运算的“操作数”和“返回值”都变得非常清晰,甚至让我在计算中有一丝享受的感觉。
原始的思想是:使用大写字母,例如A
、B
、C
、D
来表示条件;使用and
、or
和not
来表示运算符。这样子如果有一个人带标签AandB
,我们就能清晰的知道这个人的身份——既满足 not(AorB)
。
以此类推,(非(A与B))与(A或B)的人应该就是(not(AandB))and(AorB)
……真的吗?我们发现这个更简单的写法是AxorB
。对于不同的表达式,结果却相同,那我们还不如用结果来命名。
我们知道对于 AandB
、(AxorB)andA
等等就都可以改写成1000
。
这种并列计算手工算有点麻烦了,我为此搞了一个在线并列计算器。点击左下角“导入基础配置”后将列宽设置为4,在右边表达式栏里即可输入表达式。比如A and B
或者~not (A or B)
等。点击计算即可得到结果。
1000
有点长,我们就可以用十六进制表示为8
。于是标签就可以叫T_8
,仅仅三个字符的标签就可表示任意一类人群。
在命令方块串的最后,我们别忘了把这些临时标签都去掉。
读者可自己尝试将标签T_0
~T_F
都用指令实现出来,相信对上面段所介绍的逻辑运算会有更深的理解。
下方表格显示了标签T_0
~T_F
分别包含和排除了哪些情况的实体,还有各个标签的表达式。
标签 | 运算结果 | 全部符合 | 只符合 A | 只符合 B | 全都不符 | 最简表达式 |
---|---|---|---|---|---|---|
T_0 | 0000 | 排除 | 排除 | 排除 | 排除 | 0 |
T_1 | 0001 | 排除 | 排除 | 排除 | 包含 | 非(A或B) |
T_2 | 0010 | 排除 | 排除 | 包含 | 排除 | (非A)与B |
T_3 | 0011 | 排除 | 排除 | 包含 | 包含 | 非A |
T_4 | 0100 | 排除 | 包含 | 排除 | 排除 | A与(非B) |
T_5 | 0101 | 排除 | 包含 | 排除 | 包含 | 非B |
T_6 | 0110 | 排除 | 包含 | 包含 | 排除 | (A或B)与(非(A与B)) |
T_7 | 0111 | 排除 | 包含 | 包含 | 包含 | 非(A与B) |
T_8 | 1000 | 包含 | 排除 | 排除 | 排除 | A与B |
T_9 | 1001 | 包含 | 排除 | 排除 | 包含 | (非(A或B))或(A与B) |
T_A | 1010 | 包含 | 排除 | 包含 | 排除 | B |
T_B | 1011 | 包含 | 排除 | 包含 | 包含 | (非A)或B |
T_C | 1100 | 包含 | 包含 | 排除 | 排除 | A |
T_D | 1101 | 包含 | 包含 | 排除 | 包含 | A或(非B) |
T_E | 1110 | 包含 | 包含 | 包含 | 排除 | A或B |
T_F | 1111 | 包含 | 包含 | 包含 | 包含 | 1 |
可以发现这个表具有上下对称性,这是因为对于任意十六进制数
也就是说,对于任意
我们可以验证一下,比如选择
可以发现是成立的。所以如果我们已实现了T_
类似的情况还有很多。实现一个标签后就可用于计算另一个标签。使用上文中提到的并列计算工具或者直接手动进行演算,找到运算最少的方法,可以让标签的实现更加简单。
到现在为止我们一直在研究两个条件之间的运算。那么三个以上的条件怎么办呢?其实多个条件的运算就是多来几次两条件运算。只要弄懂了两条件运算,就能套到其他多个条件的运算中,一样解决。