本帖最后由 贰逼 于 2015-7-24 17:55 编辑

循环语句与条件语句结合
下一页为 循环嵌套概念作用
本章将前两章内容进行结合,
便是循环体中使用条件语句;
和条件语句中使用循环。

循环语句结合条件语句将会涉及到
循环中条件语句

时钟
  • 建立时钟
  • 时钟中条件语句

结束循环

跳过循环

循环嵌套
  • 判断条件
  • 终止循环

全索引链接
上一篇(跳过循环)--下一篇(stats用法)


§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的矩形。


将上述复原指令:



按照顺序执行:
  1. /scoreboard players add @e[type=ArmorStand,score_b=6] b 1
  2. /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循环
  1. /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ scoreboard players add @e[type=Cow,score_a=4] a 1
  2. /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=Cow,score_a=4] ~ ~ ~1
  3. /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=ArmorStand,score_b_min=6] @e[type=Cow,score_a_min=1]
复制代码

*一层a循环
  1. /execute @e[type=Cow,score_a=4] ~ ~ ~ /tp @e[type=ArmorStand,score_b=6] ~1 ~ ~
  2. /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条:
按照顺序执行:
  1. /scoreboard players add @e[type=Pig,score_c=8] c 1
  2. 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循环
  1. /execute @e[type=Pig,score_c_min=8] ~ ~ ~ scoreboard players add @e[type=ArmorStand,score_b=6] b 1
复制代码

*二层b核心
  1. /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ scoreboard players add @e[type=Cow,score_a=4] a 1
  2. /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=Cow,score_a=4] ~ ~ ~1
  3. /execute @e[type=ArmorStand,score_b_min=6] ~ ~ ~ /tp @e[type=ArmorStand,score_b_min=6] @e[type=Cow,score_a_min=1]
复制代码

*一层a循环
  1. /execute @e[type=Cow,score_a=4] ~ ~ ~ execute @e[type=Pig,score_c_min=8] ~ ~ ~ /tp @e[type=ArmorStand,score_b=6] ~1 ~ ~
  2. /execute @e[type=Cow,score_a=4] ~ ~ ~ /scoreboard players set @e[type=ArmorStand,score_b_min=6] b 0
复制代码

*二层b循环体
  1. /execute @e[type=Pig,score_c_min=8] ~ ~ ~ /tp @e[type=Pig,score_c_min=8] @e[type=ArmorStand,score_b_min=1]
  2. /execute @e[type=ArmorStand,score_b=6] ~ ~ ~ /tp @e[type=Pig,score_c=8] ~ ~1 ~
  3. /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!。


某个不可缺失的内容:


藏了一个指令:
  1. /entitydata @e[type=ArmorStand] {NoGravity:1b}
复制代码

将所有AS消除重力(能够悬空)
[groupid=546]Command Block Logic[/groupid]