前提:
数组其实是模块的一种引申,需要运用之前各种概念,在阅读本章之前需要学习前面几章.
§9.1 指针、移位、相对操作
前面介绍了数组就是这样排列的一组实体,被赋上了计分板的分数
那么如果需要操作一个元素,给每一个元素一个单独的标签再来调用显然是不行的
为了使操作一个元素更加简便,我们需要
创建一个指针,通过移位指针,相对指针操作元素.
- /summon ArmorStand ~ ~ ~ {Tags:[p]}
复制代码
其实在这里,指针就相当于一个实体的中介,对于数组中的元素操作,我们可以通过它来间接操作.
具体来说
指针就是一个和数组代表元素的实体重合的一个自由活动的实体,对于数组中单个元素操作我们需要通过这个指针来间接操作
之所以称为指针,原因是这个中介实体指向了我们需要操作的元素
所以
指针就是我们指向元素的一个实体
如果要操作指定索引的元素,我们需要让索引加或减,但是显然没有指令能直接选取实体,这个时候就需要
移动指针,使它到达索引目的点:
代表相对指针,将它x轴位移移位
因为这里指针只有一个,等价于
- /execute @e[tag=p] ~ ~ ~ /tp @e[tag=p] ~1 ~ ~
复制代码
要对元素操作,我们将
指针移到对应位置后,就要使用相对操作了.
/execute @e[tag=p] ~ ~ ~ 操作
还记得execute的相对性把,操作中要选取元素,可以使用以下关于坐标的子选择器:
r、rm、dx、dy、dz、c
举个例子,
@e[rm=0,c=1]就是非本坐标最近的实体
@e[rm=0,c=1,dx=1]就是非本坐标x轴正方向最近的实体
@e[r=0,c=-1]就是本坐标最远实体(如果有非本体的实体,将选择非本体)
图示:
图中指针从红移位到蓝,移位了4格.
如果要相对指针操作指向的元素,可以用选择器@e[r=0,tag=!p]
§9.2 创建数组
前面可能还听的云里雾里,现在用前面的概念来举个例子:
思路:
要创建一个n个元素的数组,需要移位,再相对指针生成一个元素,循环n次.
- /scoreboard objectives add l dummy
复制代码
创建一个l计分板,代表数组长度
比如数组长度为10,先将l设为10:
- /scoreboard players set @p l 10
复制代码
然后是下面模块:
- /execute @p[score_l_min=1] ~ ~ ~ tp @e[tag=p] ~1 ~ ~
- cond:/execute @e[tag=p] ~ ~ ~ summon ArmorStand ~ ~ ~ {Tags:[x]}
- cond:/scoreboard players remove @p l 1
复制代码 *这是一个for语句,执行l的变量次
每执行一次,将指针向右位移一格,再相对指针位置生成一个tag为x的实体(数组的元素)
接着我们就创建了一个拥有十个元素的数组。
当然,创建数组不止这一种方法,具体还要活用.
总体来说创建一个自定的数组,需要循环语句的支撑和相对指针来创建元素.
§9.3 获取数组位置
也许你还不懂指针作用,接下来我们可以用for来获取数组索引位置,为指针操作做准备.
思路:
比如找到p[n]位置,我们先将指针移到数组最开头位置p[0],然后循环移位n次即可.
重新创建一个指针
将指针移到p[0](此处你也可以直接相对p[0]生成指针)
- /scoreboard players set @p l 3
复制代码此处用计分板l代表需要获取的数组索引位置,所以我现在要获取p[3]的位置
- /execute @p[score_l_min=1] ~ ~ ~ tp @e[tag=p] ~1 ~ ~
- /scoreboard players remove @p l 1
复制代码 *循环位移n次
此时指针就指向了现在十字准星指向的这个元素:p[3]
(其实就是指针的坐标和代表p[3]这个元素的实体坐标重合了,方便我们选择器来找到)
§9.4 指针和移位的精确操作
在这一小节将会展示更多利用指针这种方法操作元素的例子
如果你还不清楚指针、移位、相对概念,可以看下下面这个图示:
指针移位创建数组:
指向数组位置:
接下来几个例子,将系统的展示相对指针的操作
9.4.1 对单个元素的操作
思路:先指向数组位置,再相对指针进行操作
(指向数组位置就不多说了)
- /execute @e[tag=p] ~ ~ ~ testfor @e[tag=x,score_x_min=1,r=0,c=1]
复制代码
- /execute @e[tag=p] ~ ~ ~ /scoreboard players set @e[tag=x,r=0,c=1] x 3
复制代码
- /execute @e[tag=p] ~ ~ ~ /execute @e[tag=p,rm=0,dx=1,c=1,score_x_min=1] ~ ~
- ~ /scoreboard players set @e[tag=x,r=0,c=1] x 3
复制代码
9.4.2 对多个元素的操作
思路:两个指针先分别指向数组位置,再相对指针进行操作
(指向数组位置就不多说了)
- /execute @e[tag=p0] ~ ~ ~ execute @e[tag=x,score_x_min=1,r=0,c=1] ~ ~ ~ /scoreboard players add @p b 1/execute @e[tag=p1] ~ ~ ~ execute @e[tag=x,score_x_min=1,r=0,c=1] ~ ~ ~ /scoreboard players add @p b 1
- /execute @p[score_b_min=2] ~ ~ ~ say 1
复制代码
- /execute @e[tag=p0] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num0
- /execute @e[tag=p1] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num1
- /scoreboard players operation @e[tag=num0] x += @e[tag=num1] x
复制代码
- /execute @e[tag=p0] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num0
- /execute @e[tag=p1] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num1
- /scoreboard players operation @e[tag=num0] x >< @e[tag=num1] x
复制代码
9.4.2 遍历操作
遍历每一个数组中的元素,并进行操作
以颠倒数组为例:(就是加入有四个元素的数组:1234,转化成4321)
思路:
指针1从头向尾移位,指针2从尾向头位移,互换两指针指向的值,直到两指针交汇.
- 激活模块:/scoreboard players tag @p add start
- /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p0] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num0
- /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p1] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num1
- /execute @p[tag=start] ~ ~ ~ /scoreboard players operation @e[tag=num0] x >< @e[tag=num1] x
- *互换值
- /execute @p[tag=start] ~ ~ ~ /scoreboard players tag @e[tag=num0] remove num0
- /execute @p[tag=start] ~ ~ ~ /scoreboard players tag @e[tag=num1] remove num1
- *重置互换
- /execute @e[tag=p0] ~ ~ ~ /execute @e[tag=p1,dx=-1] ~ ~ ~ /scoreboard players tag @p remove start
- *检测交汇,结束模块
- /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p0] ~ ~ ~ /tp @e[tag=p0] ~1 ~ ~
- /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p1] ~ ~ ~ /tp @e[tag=p1] ~-1 ~ ~
- *移位指针
复制代码
§9.5 宏操作
1.选择器工作,会选择所有符合条件的实体
2.execute运作,会相对所有符合条件的实体运作
因此选中一组实体,事实上指令会在执行时执行多次。
数组中,运用选择器,可以直接遍历全部数组中的元素
例如
- /scoreboard players set @e[tag=x] x 1
复制代码
不需要指针的挨个处理,
宏操作能直接实现对整个数组的操作
在使用execute时,execute尽管能控制相对执行对象执行多次,但主要执行的指令只是一条。
所以
一条指令只能遍历执行一条指令,不能交错执行多条指令。
再就是如果数组中元素过多,也许反而会对执行造成卡顿。
至于
是否使用指针操作还是宏操作,需要视情况自己斟酌
9.5.1 获取数组元素总数
思路:相对数组全部元素给一个变量值加1
- /execute @e[tag=x] ~ ~ ~ scoreboard players add sum x 1
复制代码
最后假名中sum的变量x的值为1.
同时这种方法也是不需要Stats快速获得执行成功总量的一个方法(但是比起更新实体来说,这种方法消耗更大)
9.5.2 最值和滚动数组
思路:(擂台算法)
min=+∞,数组中全部值都和min来比较谁小;
max=-∞,数组中全部值都和max来比较谁大.
- execute @e[tag=x] ~ ~ ~ scoreboard players operation min x < @e[tag=x,c=1] x
- execute @e[tag=x] ~ ~ ~ scoreboard players operation max x < @e[tag=x,c=1] x
- (@e[tag=x,c=1],表示就是目前相对执行该条指令的元素本体)
复制代码
至于一开始min,max取值,只需要取mc中计分板的最大值和最小值(计分板有十位数限制)
思路:
左移,每个元素都和右边相邻元素交换值
右移,每个元素都和左边相邻元素交换值
- execute @e[tag=x] ~ ~ ~ scoreboard players operation @e[tag=x,c=1] x >< @e[tag=x,rm=0,dx=1] x
- execute @e[tag=x] ~ ~ ~ scoreboard players operation @e[tag=x,c=1] x >< @e[tag=x,rm=0,dx=-1] x
- (规定右移是x轴正方向,@e[tag=x,rm=0,dx=1]表示右边相邻元素)
复制代码
9.5.3 分配id
给数组按照索引的顺序,将它的某一个变量的值设为其索引id
思路:
/stats该命令方块执行成功次数映射到一个计分板,直接通过execute设置分数.
- /stats 该命令方块执行成功次数 到 temp的x
- /execute @e[tag=x] ~ ~ ~ scoreboard players operation @e[tag=x,c=1] x = temp x
复制代码
9.5.4 多数组移位和相对操作
例子:交错相加
思路:整个数组移位,数组1相对数组2操作
- /tp @e[tag=x2] ~1 ~ ~
- /execute @e[tag=x1] ~ ~ ~ /scoreboard players operation @e[tag=x1,c=1] x += @e[tag=x2,r=0,c=1] x
复制代码
§9.6 多维数组
数组可以不仅限于一维,随着数据储存范围越来越广也有多维数组.
多维数组可以套用一位数组的概念和操作方法,所以不多说了.
主要来看一看多维数组分配坐标的方法,迎合前面所研究的内容,是其支持指针、宏操作.
直接通过坐标来分配多维索引,
但是最多只能3维.
适合于维度不高,操作比较复杂的数组.