群豪見他使得全然不成章法,身手又笨拙之極,無不捧腹大笑。
那挑菜漢子道:「有甚麼好笑?讓我來練練,借把劍來。」接了長劍在手,便即亂劈亂刺,出手極快,猶如發瘋一般,更引人狂笑不已。
令狐沖初時也是負手微笑,但看到十幾招時,不禁漸覺訝異......兩人的姿式固是難看之極,但劍招古樸渾厚,劍上的威力似乎只發揮得一二成,其餘的卻是蓄勢以待,深藏不露......-- <笑傲江湖>,金庸著
卡斯鐵說:「這些生物體總是看起來前所未見,事實上都是同樣的東西。」
李厄說:「這只是您的猜測,其實我們對這一切一無所知。」-- <瘟疫>,卡繆著,嚴慧瑩譯
今天跟各位讀者介紹 DeltaPahogen 專案中很重要(若不是最重要的話)的角色:隨機猴子。它是所有訓練的基準,也是打通系統與代理人溝通的重要元件。
它首先出現在 commit 09abac 裡面,作為一個打通流程的東西。後來在 commit 5ecd2e 當中具備一個純試誤代理人的行為:隨便選著點,錯了的話就將該著點座標從選項之中排除。
上述提到的第二個 commit 代表的故事,將在接下來的兩天介紹。
這樣還能出什麼 bug 呢?沒有程式碼或模組是孤島,就算一個客戶端程式可以持續沒有修正很長一段時間,但我們無法保證協定(protocol)本身也不會。現在的例子也類似,隨著遊戲系統以及遊戲伺服器端的持續調整,這些協定也在我沒有注意到的情況下飄移了。接下來就分享幾個蠢 bug,也許意義不在於描述這些應用的問題會有多麼困難,而在於指出一個事實,就是如果缺乏基本的審查與管理,那麼就算是這樣蠢的 bug 也會發生。回顧這兩個 bug 時也很慚愧地發現我當時沒有增加相對應的 unit test。
至於
說到整個疫途的遊戲引擎實作的難點,我無論如何不會說是羅盤座標的合法性判斷條件,因為這是規則書說得很清楚的事情。但是慚愧的是,我竟然在這個部份出了三次的 bug:最基本的、還是很基本的、粗心的 corner,且依序簡說。
最基本的是,一個座標的決策給到遊戲系統來,總該判斷一下邊界吧?
pub fn is_valid(&self) -> bool {
if self.x < -MAP_OFFSET.x
|| self.x > MAP_OFFSET.x
|| self.y < -MAP_OFFSET.y
|| self.y > MAP_OFFSET.y
{
return false;
}
return true;
}
這個應該是在搬移 legacy code 的時候沒有成功搬移的結果,但在沒有大量運行(多樣組態、自動對局)之前也不容易抓出。
還是很基本的是,遊戲中的羅盤階段,合法範圍並非 5x5 的全部區域。對疫病方來說,可下的著點排除了四個角,對於醫療方(或封城時的疫病方)來說則只有內部的 3x3 九宮格。
疫病方的條件:
let times = self.x * self.y;
if times <= -MAP_OFFSET.x * MAP_OFFSET.y || times > MAP_OFFSET.x * MAP_OFFSET.y {
return false;
}
醫療、或封城時的疫病方,不在 is_valid
裡面判斷,而是存在於上一層
if (g.lockdown() && g.turn == Camp::Plague) || g.turn == Camp::Doctor {
// Plague cannot outbreak when lockdown
if c.x < -1 || c.x > 1 || c.y < -1 || c.y > 1 {
return Err("Ex01");
}
}
我們在這個系列不會特別介紹上述使用到的 Coord
結構,它只是很簡單地被用來表述 2D 座標資料。其實在我後來為了編碼盤面資訊而使用 Array
系列套件的時候,才意會到應該沒有必要自己實作,少學一套適當的 Rust 工具。
最後一個 corner 發生在前述的疫病方第二組條件 times > MAP_OFFSET.x * MAP_OFFSET.y
,這會使得 (2,2)
座標沒有被這個條件排除。我在 commit 訊息當中紀錄這個尷尬的事實。應該要是大於等於(>=
)才對。
隨機猴子行為很單純,就是試,然後排除回報錯誤的著點。然而我在修復這個問題之前,偶爾還是會遇到代理人端發現自己沒有著手可下的狀況。這怎麼可能?
原來是編碼的調整造成的。在出現問題之前,隨機猴子以及我預期的 coord_client
客戶端都是在 [0,57)
的區間選擇,它對應到棋盤格 36 個,加上 5x5 羅盤排除了 4 個角的 21。這原本是沒有問題的。但是排除了四個角的 5x5 的格子,不是很容易對應 [36,57)
的值域到座標上,而我先前也的確沒有實作。
今天也是除了簡單編輯文稿如上,就幾乎沒有產出。拼了一陣,終於是提了一個 commit,實作一個略具昨日提到的殘局譜生成器的雛型。
希望可以生成合用的、客觀可評斷優劣盤面的這殘局一手詰,來讓茫然的訓練旅途增添一些方向感。