循环语句与条件语句结合
下一页为 循环嵌套概念作用
本章将前两章内容进行结合,
便是循环体中使用条件语句;
和条件语句中使用循环。
循环语句结合条件语句将会涉及到
循环中条件语句
时钟
- 建立时钟
- 时钟中条件语句
结束循环
跳过循环
循环嵌套
- 判断条件
- 终止循环
§5.4 循环嵌套
下一页为 双重for循环
5.4.0 概念
5.4.0.1 基本概念
在某些特殊的情况下,单单一个循环无法构成完全的体系,因此需要将两个循环互相关联起来。
这个关系不是普通的或且非关系,而是层层嵌套的关系。
在循环体中除了能使用普通输出(效果指令)、条件语句外,
还能使用另一个循环语句,在循环体中继续创建循环体。
5.4.0.2 例子
比如要第n个算出三角数,
显然是从1一直连加到n。
我们进一步将每一个数分解:
所以我们需要两个循环,
循环1循环体为 a=a+1,次数为1
另一个循环2循环体为 x=x+a,次数为n
这两个循环不可以是两个独立的循环,否则完成了值后无法关联,所以得不出最终值,
相反,两个循环是相互依存的关系,而且是需要执行n次 x=x+a,每个n次中又要执行a=a+1,
因此循环1被套在循环2内部:
5.4.0.3 多维(层)
上面的例子便是循环嵌套,如果说一层嵌套是一维,看作是一条水平直线不断增加,次数为其长度;
那么二层嵌套循环则是二维,是两条互相垂直的直线,而次数分别是两条边的长度;
以此类推,除二维更有多维。
5.4.0.4 作用
循环嵌套的作用就是在循环中需要另使用高层循环得到最终值,帮助底层循环得到最终值。
5.4.0.5 执行
循环嵌套的次数就像是规定一个坐标,坐标的值分别是每层嵌套的目前的次数,
因此循环嵌套将会执行这个直线/平面/空间中所有点的坐标(结束或者跳过除外),
所以在循环嵌套中每层每个循环次数都有执行的对应值。
下一页为 多重for循环
5.2.1 二层嵌套 对于二层嵌套最好的例子便是构建矩形。
for是次数循环,
如果一个循环x次的for循环中不断使某个实体向水平正方向延伸,那么得到的是一条水平直线,长度便是x;
在另一个循环z次的for循环中中,这个循环使另一个实体项竖直正方向延伸,那么得到的是一条竖直直线,长度则是z;
那么如果其中一个循环嵌套在另一个循环中,例如x套在z中
并且在第二层循环结束后x实体坐标=z坐标,
那么在x++在y的竖直坐标得到水平直线后,y竖直坐标+1;
x的坐标接着又=y的坐标,所以x++就在现在y的竖直坐标上得到水平直线;
如此循环,便得到了长宽分别为x,y的矩形。
将上述复原指令:
按照顺序执行:
- /scoreboard players add @e[type=ArmorStand,score_b=6] b 1
- /execute @e[type=Cow,score_a_min=1,score_a=4] ~ ~ ~ /execute @e[type=ArmorStand,score_b_min=1,score_b=6] ~ ~ ~ setblock ~ ~ ~ wool 15
*二层b循环
- /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ scoreboard players add @e[type=Cow,score_a=4] a 1
- /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=Cow,score_a=4] ~ ~ ~1
- /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=ArmorStand,score_b_min=6] @e[type=Cow,score_a_min=1]
*一层a循环
- /execute @e[type=Cow,score_a=4] ~ ~ ~ /tp @e[type=ArmorStand,score_b=6] ~1 ~ ~
- /execute @e[type=Cow,score_a=4] ~ ~ ~ /scoreboard players set @e[type=ArmorStand,score_b_min=6] b 0
*二层b循环体
先来看效果:
首先需要一头牛,一个装备架;
先将牛初始值a设为0
再将盔甲架初始值b设为0后,生成一个4*6矩形。
分析:
首先执行高层循环,是因为时钟的关系,
因为在时钟中,高层循环更高级,需要在低层之前执行,所以将最高层循环放在最先执行。
其中输出需要让条件在所有for循环不管高层低层的次数范围内,否则越界的结果是十分可怕的。
在低层循环中需要判断是否执行完高层循环,所以需要条件语句作为低层循环向导。
此处/execute @e[type=ArmorStand,score_b_min=6]是判断高层循环执行完,
也可以使用/execute @e[type=ArmorStand,score_b=0]判断高层循环没开始,在高层循环之前执行,不过要按照时钟来。
那么低层循环体和循环判断都需要这个向导。
最后执行二层循环b的循环体是因为时钟的原因,这一段指令必须在a执行完后执行,而循环体也是可以分开的。
总之,高层在低层前执行。
标准格式:
/scoreboard players add @e[实体选择器,score_二层循环计分板=二层次数] 二层循环计分板 1
/execute @e[实体选择器,score_一层循环计分板_min=1,score_一层循环计分板=一层次数] ~ ~ ~ /execute @e[实体选择器,score_二层循环计分板_min=1,score_二层循环计分板=二层次数] ~ ~ ~ 输出
*高层循环
/execute @e[实体选择器,score_二层循环计分板=二层次数] ~ ~ ~ scoreboard players add @e[实体选择器,score_一层循环计分板_min=1,score_一层循环计分板=低层次数] 一层循环计分板 1
/execute @e[实体选择器,score_二层循环计分板=二层次数] ~ ~ ~ 输出
*低层循环
(/execute @e[实体选择器,score_一层循环计分板_min=1,score_一层循环计分板=一层次数] ~ ~ ~ 输出)
*高层循环体(可分裂)
/execute @e[实体选择器,score_一层循环计分板_min=1,score_一层循环计分板=一层次数] ~ ~ ~ scoreboard players set @e[实体选择器,score_二层循环计分板=高层次数] 二层循环计分板 0
*重置高层循环
5.2.1 多层嵌套
(这是二层嵌套延伸)
前面使用双重嵌套构建平面,这里我们就借此拓展,使用三层嵌套构建体。
与之前想法不同,除了xz互相延伸,还需要增加一个y。
也就是在空间中让代表y的直线已知向上延伸y次。
因此指令如下:
将原本7条指令增加到了11条:
按照顺序执行:
- /scoreboard players add @e[type=Pig,score_c=8] c 1
- execute @e[type=Cow,score_a_min=1,score_a=4] ~ ~ ~ /execute @e[type=ArmorStand,score_b_min=1,score_b=6] ~ ~ ~ /execute @e[type=Pig,score_c_min=1,score_c=8] ~ ~ ~ setblock ~ ~ ~ wool 15
*三层c循环
- /execute @e[type=Pig,score_c_min=8] ~ ~ ~ scoreboard players add @e[type=ArmorStand,score_b=6] b 1
*二层b核心
- /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ scoreboard players add @e[type=Cow,score_a=4] a 1
- /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=Cow,score_a=4] ~ ~ ~1
- /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=ArmorStand,score_b_min=6] @e[type=Cow,score_a_min=1]
*一层a循环
- /execute @e[type=Cow,score_a=4] ~ ~ ~ execute @e[type=Pig,score_c_min=8] ~ ~ ~ /tp @e[type=ArmorStand,score_b=6] ~1 ~ ~
- /execute @e[type=Cow,score_a=4] ~ ~ ~ /scoreboard players set @e[type=ArmorStand,score_b_min=6] b 0
*二层b循环体
- /execute @e[type=Pig,score_c_min=8] ~ ~ ~ /tp @e[type=Pig,score_c_min=8] @e[type=ArmorStand,score_b_min=1]
- /execute @e[type=ArmorStand,score_b=6] ~ ~ ~ /tp @e[type=Pig,score_c=8] ~ ~1 ~
- /execute @e[type=ArmorStand,score_b=6] ~ ~ ~ /scoreboard players set @e[type=Pig,score_c_min=8] c 0
*三层c循环体
还是先来看效果:
(为了图方便使用单次执行模块的一种开启)
如果研究上面指令就知道除了AS代表x,Cow代表z,
还有Pig代表y。
因此单次执行顺序如下:
/summon ArmorStand ~3 ~ ~
/summon Cow ~3 ~-2 ~ {NoAI:1}
/summon Pig ~2 ~ ~ {NoAI:1}
*同一坐标生成三个中介实体
/scoreboard players set @e[type=Cow] a 0
/scoreboard players set @e[type=ArmorStand] b 0
/scoreboard players set @e[type=Pig] c 0
*分别设定基础分数
正在生成
生成4*8*6立方体完成。
分析:
与前面双重差不多,大家可以对比。
得出的客观规律依旧是:高层放在低层前执行;因为时钟,所以某些循环体必须分开。
标准格式:
/scoreboard players add @e[实体选择器,score_更高层循环计分板=更高层次数] 更高层循环计分板 1
/execute @e[实体选择器,score_低层循环计分板_min=1,score_低层循环计分板=低层次数] ~ ~ ~ /execute @e[实体选择器,score_高层循环计分板_min=1,score_高层循环计分板=高层次数] ~ ~ ~ ………… /execute @e[实体选择器,score_更高层循环计分板_min=1,score_更高层循环计分板=更高层次数] ~ ~ ~ 输出
*更高层循环
/execute @e[实体选择器,score_更高层循环计分板=更高层次数] ~ ~ ~scoreboard players add @e[实体选择器,score_高层循环计分板=高层次数] 高层循环计分板 1
*高层循环核心
/execute @e[实体选择器,score_高层循环计分板=高层次数] ~ ~ ~ scoreboard players add @e[实体选择器,score_低层循环计分板_min=1,score_低层循环计分板=低层次数] 低层循环计分板 1
/execute @e[实体选择器,score_高层循环计分板=高层次数] ~ ~ ~ 输出
*低层循环
(/execute @e[实体选择器,score_低层循环计分板_min=1,score_低层循环计分板=低层次数] ~ ~ ~ 输出)
*高层循环体(可分裂)
/execute @e[实体选择器,score_低层循环计分板_min=1,score_低层循环计分板=低层次数] ~ ~ ~ scoreboard players set @e[实体选择器,score_高层循环计分板=高层次数] 高层循环计分板 0
*重置高层循环
(/execute @e[实体选择器,score_高层循环计分板_min=1,score_高层循环计分板=高层次数] ~ ~ ~ 输出)
*更高层循环体(可分裂)
/execute @e[实体选择器,score_高层循环计分板_min=1,score_高层循环计分板=高层次数] ~ ~ ~ scoreboard players set @e[实体选择器,score_更高层循环计分板=更高层次数] 更高层循环计分板 0
*重置更高层循环
附加部分
练习:
- 还原概念中的 三角数 for嵌套模块;
- 实现阶乘,使a最终值为a!。
某个不可缺失的内容:
藏了一个指令:
- /entitydata @e[type=ArmorStand] {NoGravity:1b}
将所有AS消除重力(能够悬空)