這裡又是好久不見的雪色,
拖更好像已經是我的習慣了,完蛋(X
為了治療自己的拖更症,讓自己開始往奇怪的方向發展中
此為一系列,預計約莫1~2個月會發表一篇文章,
主要是引導國高中生、對於Minecraft指令有興趣並想深入研究的學生參考,
從中可以學習一些應用數學的計算方式、計算幾何與一些簡單的演算法概念
( ⚠ 本篇文章難度很高,請至少熟悉以下的先備知識後會比較容易閱讀 ⚠ )
execute, scoreboard, data指令
至少具備國中程度的數學能力 ─ 未知數與方程式
在此篇文章能學到什麼 ?
一、統整Minecraft的基礎計算規則與操作二、利用後序運算解析數學式三、理解單變數函數與雙變數函數
目錄
一、算術運算(Arithmetic Operation)二、比較運算(Comparison Operation)三、後序式(Suffix Expression)四、綜合運用五、次篇預告
一、算術運算(Arithmetic Operation)
1. 記分板運算(Scoreboard Operation)
記分板可以儲存 [-2147483648, 2147483647]=[-2^31, 2^31-1] 的值
在scoreboard players operation 中,一共有以下幾種的操作方式
Op 表達式 計算方式說明 += a=a+b 使a加上b的值 -= a=a-b 使a減去b的值 *= a=a*a 使a乘上b的值 /= a=a/b 使a除去b的值 %= a=a%b 使a模去b的值 (≡ a mod b),又或稱為 使a為a除b的餘數 = a=b 使a為b的值 < a=min(a,b) 使a為a和b的最小值 > a=max(a,b) 使a為a和b的最大值 >< swap(a,b) 交換a和b的值,唯一個雙向操作(bi-operation)
舉例來說,執行 /scoreboard players operation #a var >< #b var,
會將 #a 的 var 與 #b 的 var 進行交換(swap)
我們在後篇會將這些計算操作簡寫成冒號右側的映射(mapping)形式,如 swap(#a[var], #b[var])
2. 小數/浮點數運算(Floating Number Operation)
這將會在後續幾篇中進行詳細講解,包含實作過程與可以應用的操作方式
二、比較運算(Comparison Operation)
- 數值區間(range)的格式:
值 區間 條件式 比較方式說明 u [u,u] value==u 若值等於u ..u (,u] value<=u 若值小於等於u u.. [u,) value>=u 若值大於等於u v..u [v,u] v<=value<=u 若值大於等、於v小於等於u
以下我們會將數值區間的變數記做 [r]
1. 實體選擇器(Selector)
selector中有提供可以查詢scoreboard數值與區間的方式@#[score={obj=[r]}]:若目標的obj分數介於數值區間 [r] 之間
2. execute if score
相比於selector可以用來比較變數區間的情況,其額外提供了以下幾種比較方式:
< a<b 若a小於b <= a<=b 若a小於等於b = a==b 若a等於b > a>b 若a大於b >= a>=b 若a大於等於b matches [r] a∈[r] 若值介於數值區間 [r] 之間
三、後序式(Suffix Expression)
有時候觀察一個數學式子,像是一個 之類的式子都要觀察老半天,
或是看到別人寫的計算數學的函數又不知道該怎麼樣快速看的話,
我們在這裡會提供一個可以快速解析的方式
我們在這裡會提供一個可以快速解析的方式
在這裡先提及一個數學式結構的概念:
表達式 Expression | 格式 | 範例 |
前序 prefix | + a b | * + 2 3 7 |
中序 infix | a + b | ( 2 + 3 ) * 7 |
後序 postfix | a b + | 2 3 + 7 * |
中序式是我們一般解數學題目時會使用的方式,
而轉成後序式可以讓電腦更方便計算,也不用考慮到括弧的問題
而轉成後序式可以讓電腦更方便計算,也不用考慮到括弧的問題
(若對此表達式有興趣者,可以查閱網路進一步了解)
(此概念在學習程式的「資料結構」部分時會再提及到一次)
轉換中序式 為 後序式(Infix Expression to Postfix Expression)
假設現有一式:
首先步驟是將其攤平:
後續轉換的步驟是從左往右解析,而轉換後的後序式會是這樣:
我們可以將其依序解析:
在這裡要特別注意根號(√)是一個單變數函式(一元運算),他只會用掉一個數
如果不是很知道該怎麼轉換的可以利用這個線上轉換器來輔助:
知道了後序式之後能做什麼?
當然就是直接寫出指令了,還能做甚麼(?
如果還不是很了解的話,可以把「後序運算的轉換過程」看成是一個「計算流程」,
每當遇到一個運算符(Operator)時就會進行一次計算,
在這裡要如何節省變數用量就會變成很重要的一環了
如果還不是很了解的話,可以把「後序運算的轉換過程」看成是一個「計算流程」,
每當遇到一個運算符(Operator)時就會進行一次計算,
在這裡要如何節省變數用量就會變成很重要的一環了
用範例來看,已知的參數有 (x, a, b, c),在這裡我們會需要加開兩個變數 (k, p):
k = b k *= b // k == b^2 p = a p *= 4 // p == 4a p *= c // p == 4ac k -= p // k == b^2-4ac k = sqrt(k) // k == sqrt(b^2-4ac) k -= b // k == sqrt(b^2-4ac)-b p = a p *= 2 // p == 2a k /= p // k == [sqrt(b^2-4ac)-b]/2a p = x p -= k // p == x-[sqrt(b^2-4ac)-b]/2a return p as result |
(我們有稍微調動計算順序,這麼做主要是為了節省變數用量)
可以觀察我們的計算順序同樣是:* * * - - √ * / -,與後序運算的運算符是相同的,
而解析原本數學式的方式則是像//右側內容一樣來解析,將此計算流程再寫成指令的話,則可以很輕鬆的實現計算數學式的效果
通常不會特地轉成後序來看,但如果是一個計算量非常大的式子用此方式分析會很快
四、綜合運用
我們可以嘗試將上述的 算術運算 與 比較運算 的概念給綜合起來,
這就是最基礎程式計算與比較的邏輯
a = 1 b = 4 if ( a > b ) swap(a, b) if ( a <= b ) a = a + sqrt(b) // a == 1 + 2 == 3 |
如果換成用Minecraft的指令來寫,則可以寫出類似這樣子的指令:
scoreboard players set a var 1 scoreboard players set b var 4 execute if score a var > b var run scoreboard players operation a var >< b var execute unless score a var > b var run function namespace:sqrt_b execute unless score a var > b var run scoreboard players operation a var += b var |
相比於用Minecraft指令來看,用這種簡單的 虛擬碼(pseudo code) 來表達計算、程式過程會較易讀,
因此接下來的概念會以此作為前導概念進行延伸,大多數的情況都會使用這種虛擬碼的方式來表達
五、次篇預告