第四十四章 在Minecraft用指令算1+1=?
?。ㄗ⒁猓哼@一章很燒腦,建議在空閑時間大腦容量充足時閱讀,最好閱讀時在游戲內(nèi)實地操作)
我們知道,記分板中所計入的玩家分?jǐn)?shù)都是變量。既然是變量,那么多個變量是否可以互相運算呢?
答案當(dāng)然是可以。Mojang也為這個運算功能單獨提供了一個子命令:operation(操作)
operation的格式如下:
/scoreboard players operation <被跟蹤的玩家或非玩家A:目標(biāo)選擇器><計分項a><計算方式><被跟蹤的玩家或非玩家B:目標(biāo)選擇器><計分項b>
看著是不是有點迷糊?簡單來說,使用operation子命令的具體運算過程是這樣的:
第一步:使用目標(biāo)選擇器指定目標(biāo)A
第二步:指定計分項甲
?。ㄉ厦鎯刹较喈?dāng)于將目標(biāo) A在計分項甲中的分?jǐn)?shù)作為輸入a。比如,假設(shè)目標(biāo)A是張三,計分項甲是dummy型的“違法次數(shù)”,張三的違法次數(shù)是12,那么輸入a的值就是張三的違法次數(shù)的值,即a=12。)
第三步:指定計算方式(或者說是指定操作)
第四步:使用目標(biāo)選擇器指定目標(biāo)B
第五步:指定計分項乙
?。ㄉ厦娴乃摹⑽宀胶鸵?、二步同理,將目標(biāo) B在計分項乙中的分?jǐn)?shù)作為輸入b)
第六步:將輸入a和輸入b兩個量按照指定的操作進行運算。
第七步:按照指定的操作更改輸入a的和輸入b的值。(大部分操作只會更改輸入a的值,即把運算得出的值覆蓋原本輸入a的值)
舉一個簡單的例子:
/scoreboard players operation 張三 gold +=李四 gold
假設(shè)張三在gold計分項中的分?jǐn)?shù)是1,李四也一樣。那么這串指令運行過后張三在gold計分項中的分?jǐn)?shù)將會變成2(1+1),但李四的分?jǐn)?shù)還是1。
這個例子中,采用的操作(運算方式)是+=,即“求和”。具體是將輸入a(張三的gold分?jǐn)?shù))和輸入b(李四的gold分?jǐn)?shù))相加,得到結(jié)果c,并將結(jié)果c的值覆蓋原本輸入a的值。也就是說,這個“求和”是這么算的:
輸入a =結(jié)果c =輸入a +輸入b
(注意,這不是正常的數(shù)學(xué)等式。在這里有一個運算的時間先后。即最左邊的輸入a是運算完成時的輸入a,并不等于最右邊剛開始運算時“輸入a+輸入b”中的輸入a,兩者是一新一舊,不能將它們認(rèn)為是同一個“輸入a”)
操作不止有求和(+=),它一共有九種:
?。ㄗⅲ骸??”指向下取整。如?3.12?=3,?-4.82?=-5)
+=——求和
-=——求差(輸入a =結(jié)果c =輸入a -輸入b)
?。ㄈ纾? -= 1 ,結(jié)果就是2-1=1)
*=——求積(輸入a =結(jié)果c =輸入a ×輸入b)
?。ㄈ纾? *= 3,結(jié)果就是2×3=6)
/=——求商(輸入a =結(jié)果c =?輸入a ÷輸入b?)
?。ㄈ纾?4 /= 12,結(jié)果就是24÷12=2;17 /= 13,結(jié)果就是?17÷13?=1)
%=——求余(輸入a =結(jié)果c =輸入a mod 輸入b =輸入a -?輸入a ÷輸入b?×輸入b。簡單點的說法就是:輸入a =(輸入a ÷輸入b)的余數(shù))
[注:Java1.13.1版本更新中,%=的內(nèi)部代碼運算采用的某個方法從原本的%改成了Math.floorMod。不知道這會造成什么影響。我尚未在1.13.1和以上版本中進行相關(guān)實驗。]
?。ㄈ纾?7 /= 13,結(jié)果就是17-?17÷13?×13=17-1×13=17-13=4)
=——賦值(輸入a =結(jié)果c =輸入b。即把輸入b的值覆蓋到輸入a上)[注:Java1.8以下版本沒有]
?。ㄈ纾?5 = 6,結(jié)果就是6)
<——取較小值(如果輸入a ≥輸入b ,輸入a =結(jié)果c =輸入b;如果輸入a ≤輸入b,輸入a =結(jié)果c =輸入a)[注:Java1.8以下版本沒有]
(如:17 < 13 ,結(jié)果就是13)
>——取較大值(如果輸入a ≥輸入b ,輸入a =結(jié)果c =輸入a;如果輸入a ≤輸入b,輸入a =結(jié)果c =輸入b)[注:Java1.8以下版本沒有]
?。ㄈ纾?3 > 17 ,結(jié)果就是17)
><——互相交換值(輸入a 和輸入b值互換)[注:Java1.8以下版本沒有]
(如 4 >< 19,結(jié)果是“輸入a=19,輸入b=4”)
這似乎有點燒腦?沒關(guān)系,下面還有更燒腦的。operation實際上是個很復(fù)雜的東西,將其了解透后你的邏輯運算能力應(yīng)該能變強幾分。
我們知道,目標(biāo)選擇器可以選擇多個目標(biāo)。而你有沒有注意到,剛才我們所了解的不過都是輸入a和輸入b均都為1個的情況。那么如果輸入a有多個,或是輸入b有多個,甚至是輸入a和輸入b都有多個的時候,operation又會怎樣運算?
由于接下來的內(nèi)容Minecraft Wiki并未記載(注:英文Minecraft Wiki有兩行記載,但講得過于簡略),網(wǎng)上也搜不到相關(guān)內(nèi)容,下面內(nèi)容都是作者在Java1.12.2版本中實驗得出的。如果你對此很感興趣,你也可以自己嘗試去做做實驗,看看在其他版本下或其他情況下結(jié)果是否一樣。
?、佼?dāng)輸入a有多個分?jǐn)?shù),而輸入b僅有一個分?jǐn)?shù)時
現(xiàn)在我們假設(shè)輸入a有三個:
a?=1
a?=0
a?=-1
輸入b有一個:
b=3
我們對這三個輸入a和輸入b進行+=(求和)操作,最終得出來結(jié)果是:
a?=c?=a?+b=1+3=4
a?=c?=a?+b=0+3=3
a?=c?=a?+b=-1+3=2
因此不難發(fā)現(xiàn),當(dāng)有多個輸入a但只有一個輸入b時,游戲?qū)衙總€輸入a均與輸入b進行一次運算操作。
?。ㄗⅲ哼@不是真正的實驗過程,這已經(jīng)被大大簡化了)
?、诋?dāng)輸入a有一個分?jǐn)?shù),而輸入b有多個分?jǐn)?shù)時
我們假設(shè)輸入a=1,輸入b有三個:
b?=2
b?=3
b?=-4
我們對這個輸入a和三個輸入b進行+=操作,最終得出結(jié)果是:
a=c=a+b?+b?+b?=1+2+3+(-4)=2
不難發(fā)現(xiàn),當(dāng)輸入a只有一個但輸入b有多個時,輸入a將與每個輸入b都進行一次運算操作,再把最終得出的結(jié)果覆蓋到原本的輸入a上。
?、郛?dāng)輸入a和輸入b均為多個分?jǐn)?shù)時(該情況Minecraft Wiki并未記載):
我們假設(shè)輸入a有兩個:
a?=1
a?=0
輸入b也有兩個:
b?=3
b?=-2
我們也對它們進行+=操作,最終得出的結(jié)果竟然是:
a?=c?=a?+b?=1+3=4
a?=c?=a?+b?=0+3=3
沒錯!輸入a和輸入b多個的情況下,游戲只會選擇一個輸入b來參與運算。也就是說,在其他條件相同的情況下,該結(jié)果跟輸入a多個但輸入b只有一個的結(jié)果一模一樣。
這應(yīng)該算是個Bug吧......
對了,既然游戲只會選擇一個輸入b來參與運算,那么這個輸入b會選擇誰呢?
根據(jù)作者的測試,游戲會選擇目標(biāo)選擇器排列的第一個輸入b,這時候就要看你用的目標(biāo)選擇器。如果用的是@p、@e、@a,就是就近原則;如果是@r,則是隨機。
這個排列順序在operation中不只是用于選擇輸入b,它還用于在情況①下決定輸入a們與輸入b運算的先后順序和情況②中決定輸入a和哪些輸入b先運算,哪些輸入b后運算。
了解這些后,我們就可以來看一種升級版的情況①:
當(dāng)輸入a有多個,輸入b有一個且這個輸入b也是一個輸入a時
這個情況是啥意思呢?簡單來說,現(xiàn)在有張三李四王五,我們拿他們?nèi)姆謹(jǐn)?shù)作為三個輸入a,并把張三的分?jǐn)?shù)也作為輸入b。是不是復(fù)雜了起來?
我們假設(shè)有三個輸入a,分別是:
a?=-2
a?=1
a?=3
(按照下標(biāo)數(shù)字從小到大參與運算)
而輸入b就是a?。
我們對它們兩按照該情況進行+=運算,最終得出來以下結(jié)果:
a????=c?=a????+a????=-2+1=-1
a????=c?=a????+a????=1+1=2
a????=c?=a????+a????=3+2=5
上面兩個式子中,為了讓大家方便理解,我特別標(biāo)上了old(舊)和new(新)來代表未運算和已運算的兩個不同的量。
不難發(fā)現(xiàn),當(dāng)輸入a有多個,并且輸入b是眾多輸入a中的一個時,如果某個輸入a與輸入b運算時這個輸入b所關(guān)系的輸入a還沒有運算,那么這個輸入a將會與舊的輸入b進行運算;如果某個輸入a與輸入b運算時這個輸入b所關(guān)系的輸入a已運算完成,那么這個輸入a將會與新的輸入b進行運算。
這讀起來有點繞口啊。沒關(guān)系,雖然現(xiàn)在你不一定看得懂,但只要你在游戲中實地做過實驗?zāi)愎烙嬀投恕?p> 本章就到這里......了?
剛才的四個探究中,我們都在探究operation在有多個輸入和多個輸出情況下會如何計算。一般來說,進行這種研究會用到命令方塊。你知道的,命令方塊運行指令成功后會輸出結(jié)果,這個結(jié)果可能會影響到命令方塊輸出的紅石信號強度。比如我們之前講到的testfor指令,探測到有多少個實體就輸出多強紅石信號。
那么operation在命令方塊中執(zhí)行成功是否會影響到命令方塊輸出的紅石信號強度呢?
答案是:能!
經(jīng)過作者的測試,operation運行一次輸出的紅石信號強度,等于該次operation計算的次數(shù)。比如情況①中,如果指令是在命令方塊中運行,那么運行成功后命令方塊將輸出3級紅石信號,因為operation運算了3次。情況②輸出的信號也一樣,別看作者給出的只是一行式子,但是operation仍然確確實實運算了3次。
這是一個冷門到極致的知識,冷門到連Minecraft Wiki也沒有記載。當(dāng)然我也不確定在新版本是否還有這個功能,也許已經(jīng)被移除了呢?