本帖最后由 贰逼 于 2016-8-21 18:55 编辑

§1.10补丁-数组
对1.9模块的引申补充

Chm文档下载
§9 数组(索引在上方,点击文字即可跳转)
我们1.11再会.

模块总索引
1.9补丁链接下面的小图是因为编辑器问题,见谅...




数组
数据寄存在一个实体中显然是不够的,为了实现对数据批量的操作,引入了数组的概念:p

数组就是一组有序排列的数据,但综合mc还原的情况,在这里数组事实上就是一组有序排列的实体组合
一般来说这里的实体组合都是坐标上有序的方向(例如x+ z+)

对数组的操作本质上就是对一组数据的集合的操作,
其中这一组数据全部就是数组,一个数据是元素,数据的位置id是索引

本章将初步还原各种对数组操作的方法,包括:
创建、索引、元素的操作和遍历的操作.

概念:

在此处模块中,数组就是一组排列的实体,每个实体都拥有变量 也就是p

元素,就是其中的一个实体; 也就是p
索引,就是一个实体从某个起始实体开始坐标的顺序.(为了结合选择器进行操作,一般实体坐标间隔为1) 也就是i

图示:

前提:
数组其实是模块的一种引申,需要运用之前各种概念,在阅读本章之前需要学习前面几章.


§9.1 指针、移位、相对操作
  • 指针
前面介绍了数组就是这样排列的一组实体,被赋上了计分板的分数
那么如果需要操作一个元素,给每一个元素一个单独的标签再来调用显然是不行的
为了使操作一个元素更加简便,我们需要创建一个指针,通过移位指针,相对指针操作元素.
  1. /summon ArmorStand ~ ~ ~ {Tags:[p]}
复制代码

其实在这里,指针就相当于一个实体的中介,对于数组中的元素操作,我们可以通过它来间接操作.
具体来说指针就是一个和数组代表元素的实体重合的一个自由活动的实体,对于数组中单个元素操作我们需要通过这个指针来间接操作
之所以称为指针,原因是这个中介实体指向了我们需要操作的元素
所以指针就是我们指向元素的一个实体

  • 移位
如果要操作指定索引的元素,我们需要让索引加或减,但是显然没有指令能直接选取实体,这个时候就需要移动指针,使它到达索引目的点
  1. /tp @e[tag=p] ~1 ~ ~
复制代码
代表相对指针,将它x轴位移移位
因为这里指针只有一个,等价于
  1. /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次.
  1. /scoreboard objectives add l dummy
复制代码

创建一个l计分板,代表数组长度

比如数组长度为10,先将l设为10:
  1. /scoreboard players set @p l 10
复制代码

然后是下面模块:
  1. /execute @p[score_l_min=1] ~ ~ ~ tp @e[tag=p] ~1 ~ ~
  2. cond:/execute @e[tag=p] ~ ~ ~ summon ArmorStand ~ ~ ~ {Tags:[x]}
  3. cond:/scoreboard players remove @p l 1
复制代码
*这是一个for语句,执行l的变量次
每执行一次,将指针向右位移一格,再相对指针位置生成一个tag为x的实体(数组的元素)

接着我们就创建了一个拥有十个元素的数组。

当然,创建数组不止这一种方法,具体还要活用.
总体来说创建一个自定的数组,需要循环语句的支撑和相对指针来创建元素.


§9.3 获取数组位置
也许你还不懂指针作用,接下来我们可以用for来获取数组索引位置,为指针操作做准备.
思路:
比如找到p[n]位置,我们先将指针移到数组最开头位置p[0],然后循环移位n次即可.

重新创建一个指针
  1. /tp @e[tag=p] ~1 ~ ~
复制代码
将指针移到p[0](此处你也可以直接相对p[0]生成指针)
  1. /scoreboard players set @p l 3
复制代码
此处用计分板l代表需要获取的数组索引位置,所以我现在要获取p[3]的位置

  1. /execute @p[score_l_min=1] ~ ~ ~ tp @e[tag=p] ~1 ~ ~
  2. /scoreboard players remove @p l 1
复制代码
*循环位移n次

此时指针就指向了现在十字准星指向的这个元素:p[3]
(其实就是指针的坐标和代表p[3]这个元素的实体坐标重合了,方便我们选择器来找到)


§9.4 指针和移位的精确操作
在这一小节将会展示更多利用指针这种方法操作元素的例子

如果你还不清楚指针、移位、相对概念,可以看下下面这个图示:
指针移位创建数组:

指向数组位置:

接下来几个例子,将系统的展示相对指针的操作


        9.4.1 对单个元素的操作
思路:先指向数组位置,再相对指针进行操作

(指向数组位置就不多说了)
  • 检测值
  1. /execute @e[tag=p] ~ ~ ~ testfor @e[tag=x,score_x_min=1,r=0,c=1]
复制代码

  • 修改值
  1. /execute @e[tag=p] ~ ~ ~ /scoreboard players set @e[tag=x,r=0,c=1] x 3
复制代码

  • 与条件结合
  1. /execute @e[tag=p] ~ ~ ~ /execute @e[tag=p,rm=0,dx=1,c=1,score_x_min=1] ~ ~
  2. ~ /scoreboard players set @e[tag=x,r=0,c=1] x 3
复制代码


        9.4.2 对多个元素的操作
思路:两个指针先分别指向数组位置,再相对指针进行操作

(指向数组位置就不多说了)
  • 检测(且)
  1. /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
  2. /execute @p[score_b_min=2] ~ ~ ~ say 1
复制代码

  • 运算(相加为例)
  1. /execute @e[tag=p0] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num0
  2. /execute @e[tag=p1] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num1
  3. /scoreboard players operation @e[tag=num0] x += @e[tag=num1] x
复制代码

  • 比较和互换(互换为例)
  1. /execute @e[tag=p0] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num0
  2. /execute @e[tag=p1] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num1
  3. /scoreboard players operation @e[tag=num0] x >< @e[tag=num1] x
复制代码



        9.4.2 遍历操作
遍历每一个数组中的元素,并进行操作
以颠倒数组为例:(就是加入有四个元素的数组:1234,转化成4321)
思路:
指针1从头向尾移位,指针2从尾向头位移,互换两指针指向的值,直到两指针交汇.
  1. 激活模块:/scoreboard players tag @p add start

  2. /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p0] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num0
  3. /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p1] ~ ~ ~ /scoreboard players tag @e[tag=x,score_x_min=1,r=0,c=1] add num1
  4. /execute @p[tag=start] ~ ~ ~ /scoreboard players operation @e[tag=num0] x >< @e[tag=num1] x
  5. *互换值

  6. /execute @p[tag=start] ~ ~ ~ /scoreboard players tag @e[tag=num0] remove num0
  7. /execute @p[tag=start] ~ ~ ~ /scoreboard players tag @e[tag=num1] remove num1
  8. *重置互换

  9. /execute @e[tag=p0] ~ ~ ~ /execute @e[tag=p1,dx=-1] ~ ~ ~ /scoreboard players tag @p remove start
  10. *检测交汇,结束模块

  11. /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p0] ~ ~ ~ /tp @e[tag=p0] ~1 ~ ~
  12. /execute @p[tag=start] ~ ~ ~ /execute @e[tag=p1] ~ ~ ~ /tp @e[tag=p1] ~-1 ~ ~
  13. *移位指针
复制代码



§9.5 宏操作
  • 原理
1.选择器工作,会选择所有符合条件的实体
2.execute运作,会相对所有符合条件的实体运作
因此选中一组实体,事实上指令会在执行时执行多次。
  • 概念
数组中,运用选择器,可以直接遍历全部数组中的元素
例如
  1. /scoreboard players set @e[tag=x] x 1
复制代码

不需要指针的挨个处理,宏操作能直接实现对整个数组的操作
  • 事项
在使用execute时,execute尽管能控制相对执行对象执行多次,但主要执行的指令只是一条。
所以一条指令只能遍历执行一条指令,不能交错执行多条指令

再就是如果数组中元素过多,也许反而会对执行造成卡顿。

至于是否使用指针操作还是宏操作,需要视情况自己斟酌

        9.5.1 获取数组元素总数
思路:相对数组全部元素给一个变量值加1
  1. /execute @e[tag=x] ~ ~ ~ scoreboard players add sum x 1
复制代码

最后假名中sum的变量x的值为1.

同时这种方法也是不需要Stats快速获得执行成功总量的一个方法(但是比起更新实体来说,这种方法消耗更大)

        9.5.2 最值和滚动数组
  • 最值(数组元素中最小值和最大值)
思路:(擂台算法)
min=+∞,数组中全部值都和min来比较谁小;
max=-∞,数组中全部值都和max来比较谁大.
  1. execute @e[tag=x] ~ ~ ~ scoreboard players operation min x < @e[tag=x,c=1] x
  2. execute @e[tag=x] ~ ~ ~ scoreboard players operation max x < @e[tag=x,c=1] x
  3. (@e[tag=x,c=1],表示就是目前相对执行该条指令的元素本体)
复制代码

至于一开始min,max取值,只需要取mc中计分板的最大值和最小值(计分板有十位数限制)

  • 滚动数组(全部元素左移右移,末位数组归初位)
思路:
左移,每个元素都和右边相邻元素交换值
右移,每个元素都和左边相邻元素交换值
  1. execute @e[tag=x] ~ ~ ~ scoreboard players operation @e[tag=x,c=1] x >< @e[tag=x,rm=0,dx=1] x
  2. execute @e[tag=x] ~ ~ ~ scoreboard players operation @e[tag=x,c=1] x >< @e[tag=x,rm=0,dx=-1] x
  3. (规定右移是x轴正方向,@e[tag=x,rm=0,dx=1]表示右边相邻元素)
复制代码


        9.5.3 分配id
给数组按照索引的顺序,将它的某一个变量的值设为其索引id
思路:
/stats该命令方块执行成功次数映射到一个计分板,直接通过execute设置分数.
  1. /stats 该命令方块执行成功次数 到 temp的x
  2. /execute @e[tag=x] ~ ~ ~ scoreboard players operation @e[tag=x,c=1] x = temp x
复制代码


        9.5.4 多数组移位和相对操作
例子:交错相加
思路:整个数组移位,数组1相对数组2操作
  1. /tp @e[tag=x2] ~1 ~ ~
  2. /execute @e[tag=x1] ~ ~ ~ /scoreboard players operation @e[tag=x1,c=1] x += @e[tag=x2,r=0,c=1] x
复制代码


§9.6 多维数组
数组可以不仅限于一维,随着数据储存范围越来越广也有多维数组.
多维数组可以套用一位数组的概念和操作方法,所以不多说了.
主要来看一看多维数组分配坐标的方法,迎合前面所研究的内容,是其支持指针、宏操作.

  • 空间维度分配方法

直接通过坐标来分配多维索引,
但是最多只能3维.
适合于维度不高,操作比较复杂的数组.
  • 嵌套分配方法

通过嵌套数组中各个索引和访问来分配维度
(图中方形代表二维数组p[j]中的i,直线是i的[j])
适用于高于三维,但操作复杂,难以整体宏操作,所以推荐是简单的高维数组.

§9.7 结合结构方块
结构方块可以复制实体,因此我们可以使用结构方块快速复制、翻转数组

保存数组到一个结构

复制粘贴这个数组

翻转数组.

因此我们不需要相对操作来继承数组,也可以直接进行复制和翻转操作

§9.8 总结和前瞻
  • 总结
数组就是这样的数据储存方式,我们从概念谈到了操作,也引申到了一些新的想法,下面总结一下:
概念:
一维数组-线性数组
二维数组-平面数组
多维数组-多轴关系数组

操作:
指针操作-对于一个元素精确的操作,结合循环语句移位指针和相对指针对元素操作;
宏操作-对一个数组全部元素遍历操作,使用execute和选择器的操作.
当然具体操作不仅限前面所举的例子,具体要看情况来自己考虑方法,找到最简的最优的途径.

  • 前瞻
利用数组来实现的事情太多了,数组本身是一个储存数据的格式,但结合多种多样丰富的操作,扩大了单个变量的范围,实现了多个变量集体的操作方式。
在模块,此处数组也只是粗陋地利用之前的概念还原的一种思想,不过可想的事还有许多,期待各位利用数组来实现更多命令方块的方法.

我们1.11再会.


[groupid=546]Command Block Logic[/groupid]

2016-08-20_15.34.46.png (85.81 KB, 下载次数: )

2016-08-20_15.34.46.png

2016-08-20_15.36.51.png (71.56 KB, 下载次数: )

2016-08-20_15.36.51.png

2016-08-20_15.36.52.png (5.92 KB, 下载次数: )

2016-08-20_15.36.52.png

2016-08-20_15.36.53.png (9.95 KB, 下载次数: )

2016-08-20_15.36.53.png

2016-08-20_15.36.55.png (5.97 KB, 下载次数: )

2016-08-20_15.36.55.png

2016-08-20_15.36.56.png (3.85 KB, 下载次数: )

2016-08-20_15.36.56.png

2016-08-20_15.36.58.png (6.23 KB, 下载次数: )

2016-08-20_15.36.58.png

2016-08-20_15.36.59.png (6.05 KB, 下载次数: )

2016-08-20_15.36.59.png

2016-08-20_15.36.60.png (6.06 KB, 下载次数: )

2016-08-20_15.36.60.png

2016-08-20_15.36.61.png (18.64 KB, 下载次数: )

2016-08-20_15.36.61.png

2016-08-20_15.36.62.png (2.9 KB, 下载次数: )

2016-08-20_15.36.62.png

2016-08-20_15.36.63.png (2.96 KB, 下载次数: )

2016-08-20_15.36.63.png

2016-08-20_15.36.64.png (4.98 KB, 下载次数: )

2016-08-20_15.36.64.png

2016-08-20_15.36.65.png (5.28 KB, 下载次数: )

2016-08-20_15.36.65.png

2016-08-20_15.36.66.png (4.24 KB, 下载次数: )

2016-08-20_15.36.66.png

2016-08-20_15.36.67.png (4.45 KB, 下载次数: )

2016-08-20_15.36.67.png

2016-08-20_15.36.68.png (5.41 KB, 下载次数: )

2016-08-20_15.36.68.png

2016-08-20_15.36.69.png (7.31 KB, 下载次数: )

2016-08-20_15.36.69.png

2016-08-21_13.37.18.png (85.53 KB, 下载次数: )

2016-08-21_13.37.18.png

2016-08-21_13.44.38.png (83.11 KB, 下载次数: )

2016-08-21_13.44.38.png

2016-08-21_16.25.57.png (67.04 KB, 下载次数: )

2016-08-21_16.25.57.png

2016-08-21_16.26.24.png (88.51 KB, 下载次数: )

2016-08-21_16.26.24.png

2016-08-21_16.27.52.png (54.42 KB, 下载次数: )

2016-08-21_16.27.52.png

2016-08-20_15.36.57.png (3.83 KB, 下载次数: )

2016-08-20_15.36.57.png