接下來,以我開發的 Discord BOT 為例,來看看怎麼靈活應用前面所學吧!
接下來會用實戰演練的角度出發,以我的 Discord BOT 為例,去實作出一個符合需求的 Discord BOT 出來。在這個過程中,各位可以思考看看,如果是你,會怎麼實作這些功能?
今天以說明 Discord BOT 的需求為主,同時也會盡量說明這些需求背後的原因。
在介紹之前,需要先稍微解釋一下遊戲機制。
遊戲中有一類稱為「線索」的道具,一共有編號 1 到 7 號七種不同的線索,玩家每天可以隨機蒐集到數個線索。當玩家蒐集完整一套 (1 到 7 號) 線索之後,可以獲得遊戲獎勵。此外,玩家也可以贈送線索給其他玩家,贈送和接收線索同樣也可以獲得遊戲獎勵,但接收來的線索不能再繼續轉送。不過,接收線索的獎勵有每日上限,一天最多拿三次。
其他沒那麼重要的細節就省略了
這一個部分比較偏數學,會介紹計算最佳化結果的思路,與 Discord BOT 的需求有一點點關係。不過,就算直接跳過頂多只是不理解為何要開那樣的需求規格而已,不影響後續實作 Discord BOT。
懶人包:這個計算最佳化的程式,會需要評估在各種情況下的所有交換組合之中,哪個做法最好。不過,計算量可能很大,因此這部分不會使用 Python 計算。
先從比較簡單的情況開始討論。
當玩家 A 與玩家 B 各有一套完整線索時,最理想的做法是,玩家 A 和玩家 B 把所有的線索都互相交換,既可以拿到贈送與接收的獎勵,也可以拿到蒐集完整的獎勵。
如果有三個玩家各有一套完整線索時,就是三個人互換,也是 A 給 B,B 給 C,C 再給 A。
讓我們換個方式來表達:
A -> B 1234567
B -> C 1234567
C -> A 1234567
當然,要完全反過來也可以,所以 3 個玩家時,一共有 2 種做法。
從這時候開始,可能的做法開始變多了。我們可以 4 個人依序給下一個人,也可以倆倆分組進行對換。
A -> B 1234567
B -> C 1234567
C -> D 1234567
D -> A 1234567
或是
A -> B 1234567
B -> A 1234567
C -> D 1234567
D -> C 1234567
此時,可能的做法變成是 4!/4 (一個給一個) + (C 4 取 2)/2 (分成兩組),也就一共是 9 種做法。
這邊就不列詳細的計算過程了,直接秀結果。
目前我們一共有 8 位玩家... 😨
假如每位玩家都只有部分的線索,那就只交換該玩家所擁有的線索,並且只會有同號線索交換 (不會有線索 2 換線索 5 的狀況發生)。
例如玩家 A 有 123,玩家 B 有 234,玩家 C 有 1234,那麼
就 2、3 號線索三人互換,1 號線索 AC 互換,4 號線索 BC 互換。
以下就會是一個可能的做法:
A -> B 23
A -> C 1
B -> C 234
C -> A 123
C -> B 4
由於交換完的線索有保存期限的問題 (10 天),所以拿到線索就立刻拿出去交換不一定是個好選擇,有時候等確定已經湊滿一套再交換會是比較穩妥的作法。
因此,應該要把當天的線索分成兩部分:
如果把前一個範例的狀況再調整一下:
以下會是一個可能的做法:
A -> B 23
B -> C 234
C -> A 23
C -> B 4
注意到了嗎?此時,玩家 A 的 1 號線索就沒有參與交換,畢竟它沒有把它列入一定要交換的線索。而玩家 B 雖然沒有一定要換 4 號線索,但因為玩家 C 想要換,而在場的只剩下玩家 B 有,所以玩家 B 參與了 4 號線索的交換。
這種討論交換線索的問題,這其實跟一個經典的數學問題非常像,那就是:錯排問題
有 n 個元素排成一列。如果這 n 個元素都不在原本位置上,這樣的排列就稱為錯排。
不過,我們要計算的不是有一共有多少種可能的做法,而是要知道從這些可能的做法中,哪個對我們來說最好?此外,對於那些可換可不換的線索,到底是要換還是不要換?
所以,需要有一個評分機制,來幫助我們判斷哪個做法比較好。不過,評分機制就跟 Discord BOT 沒有任何關係了,這邊就不繼續討論了。
這個計算最佳化的程式,會需要評估在各種情況下 (有些線索可換可不換) 的所有交換組合 (例如:四人到底是倆倆交換還是依序傳遞一輪比較好?) 之中,哪個做法最好。
這個計算程式的計算量,會受到三個因素影響:
尤其是第三個,每多一個這樣的線索,需要評分的可能做法數量就直接翻倍。這導致這個計算可能會非常花時間,因此這個計算程式是選擇用 C 語言做開發的。
不是我寫的,我對 C 語言一竅不通...
這部分我選擇的做法是,把 C 語言的計算程式編譯成一個執行檔,輸入和輸出就靠讀寫 txt 檔,Python 只要把計算程式所需的資料寫入一個檔案,等計算完畢後,再去讀取另一個專門記錄結果的檔案。
在列出需求規格之前,還需要設想一下預期的操作流程。規劃如下:
接下來,就是設想各種情境,並列出使用者故事:
補充:「在頻道內輸入線索」簡稱為「報線索」
今天主要是介紹我對於我的 Discord BOT 的功能需求,並說明背後的原因 (遊戲機制)。最後,大家可以思考看看,如何使用 discord.py
完成上面所條列出來的功能?