從錯誤假設到 16/16:TG+OpenCode 如何完成踩地雷 Web App

小型遊戲很容易讓人以為「畫面能動就算完成」。但對 Agent 來說,真正的挑戰是把規則、測試與瀏覽器中的實際狀態對齊。

一、需求:從 Telegram Topic 到可玩的 Web App

從一個看似簡單的需求開始

本案例是 Agent 平台端到端驗收的內部示範,目的在驗證需求拆解、測試、瀏覽器驗收與人工回饋閉環,非對外產品。

2026 年 5 月 16 日,我們在一個全新的 Telegram 專案裡提出第一個實際開發任務。使用者要的是一個打開瀏覽器就能玩的踩地雷 Web App:桌面與手機都要能用,提供 Beginner、Intermediate、Expert 三種難度,還要有首次點擊安全、空白區域 Flood 展開、左鍵揭露格子、右鍵或長按插旗、計時、剩餘雷數、勝負與 Reset。

我們把「寫出來」和「證明它真的能用的條件」一起寫在我們送入 TG 的提示詞中,讓 Agent 不只要交付頁面,也要補上自動化測試,再把服務跑起來,最後用真實瀏覽器操作並檢查 Console。這個差別很重要,因為一個看起來能點的盤面,可能仍然在旗標、首次點擊或勝負判定上違反經典踩地雷規則。

二、Agent 規劃與實作

收到任務後,Agent 先檢查可重用的知識與模組,但紀錄顯示沒有適合直接套用的踩地雷實作,於是它選擇零依賴的 JavaScript ES module,加上 Node 內建的 node:test。這個選擇讓核心規則可以脫離畫面單獨測試,也避免把一個小型 Demo 綁在不必要的框架或套件上。

Agent 先建立 game.js 定義好遊戲的核心,再補上 15 項早期行為測試,之後才接上 UI 的 pointer 事件、計時器、旗標計數與訊息提示,最後補上靜態伺服器與瀏覽器檢查。實作裡的三個尺寸與雷數是 Beginner 9×9/10 雷、Intermediate 16×16/40 雷、Expert 30×16/99 雷;首次揭露時會保護點擊格及旁邊的格子,避免玩家一開始就被隨機配置淘汰。

三、測試錯誤:測試本身曾出現的錯誤

紅字不一定代表產品壞掉

踩地雷第一次跑測試時,畫面還沒真正被玩家打開,系統後端就已經先遇到幾個紅字。但這些紅字不全是遊戲規則寫錯。有一次只是 node --test 指到資料夾,而不是指到真正的測試檔。

另一個例子是工程師納入流程的瀏覽器驗收腳本判斷錯地雷位置。它原本想模擬玩家插旗,但它不是直接知道哪一格是地雷,而是從畫面狀態和剩餘雷數去推測。推錯之後,它把旗子插在錯的地方,後續操作就讓流程看起來像遊戲輸了。這不是玩家正常遊玩時遇到的產品錯誤,而是驗收腳本自己的判斷失誤。

這件事對我們很重要,因為它讓整個流程先建立一個基本判斷:看到測試失敗時,不能直接假設產品壞掉。要先問清楚失敗來自哪裡,是需求規則、遊戲程式、測試寫法,還是瀏覽器操作腳本自己的誤判。踩地雷這個案例後面之所以能整理成技術文章,就是因為它把這幾層分開了。當然測試本身的錯誤其實還是少數,確實還是有很多錯誤是真實錯誤。

四、人工驗證:畫面能動,還不代表規則完整

第一輪交付後,Agent 已經可以打開一個看起來完整的踩地雷:有 9×9、16×16、30×16 三種棋盤,有剩餘雷數、有計時器、有重新開始,也能點開空白區域。它也回報測試通過,並用 Chrome DevTools 看過畫面、點過格子、切換過難度。就展示效果來說,這時候已經很像一個完成品。

我們後來特別檢查一個容易漏掉的情境:玩家先在某格插旗,接著點開旁邊一大片空白區域。正常踩地雷裡,被玩家插旗的格子應該被保護起來,就算旁邊空白格自動展開,也不能把那個旗標格一起打開。

這裡就抓到真正的產品問題。系統原本在展開空白區域時,把已插旗的安全格也當成普通格子處理。換成人話說,就是玩家明明已經標記「這格先不要碰」,遊戲卻在自動展開時偷偷碰了它。

五、使用者回饋後,系統怎麼修正

我們把這個問題回饋給系統後,系統把「插旗格不可被自動展開」變成一條明確規則。系統接著補上對應測試:先放一個固定棋盤,刻意在會被空白展開波及的位置插旗,再點開旁邊空白格。正確結果必須是旗子還在,那格也仍然保持未打開。

用可重現測試建立底線

這個測試的價值在於,它把玩家行為寫成一個可重複的驗收情境。後來系統固定使用 seed 1 這個棋盤:先在 (0,1) 插旗,再點開旁邊會展開空白區域的格子。正確結果必須是 (0,1) 的旗子還在,而且那格沒有被打開。

為了確認測試真的有用,我們還做過一次反向檢查:暫時拿掉保護旗標的邏輯,測試就會失敗;把正式修正放回來,測試才重新通過。這代表它真的能抓到那個錯,而不是一個永遠都會過的形式測試。

另一個使用者回饋比較偏視覺:深色主題裡,「還沒打開的格子」和「已經打開但沒有數字的空白格」顏色太像。這不會破壞遊戲規則,但會讓玩家不容易看出自己到底開過哪些地方。系統後來只調整空白格的顏色和邊界,沒有動到遊戲邏輯;修完後再用瀏覽器量實際畫面顏色,確認兩種狀態比原本更容易區分。

六、瀏覽器驗收:用真實瀏覽器補上最後一層證據

自動測試能證明規則,但不能完全取代瀏覽器。因為玩家最後看到的是網頁,不是測試報告。所以這個 Demo 最後還用 Chrome DevTools 直接操作畫面:確認初始棋盤是乾淨的,第一次點擊不會踩雷,右鍵可以插旗,插旗後剩餘雷數會減少,再取消旗標會加回來。

驗收也沒有停在 Beginner 棋盤。系統切換到 Intermediate 和 Expert,確認更大的棋盤仍然能正確排版和操作。接著走兩條結局:一條是真的踩到雷,畫面進入失敗狀態並揭露地雷;另一條是真的把 Beginner 的 71 個安全格全部打開,遊戲才判定勝利。這裡特別確認過,單純把地雷都插旗不會被提前算贏,因為踩地雷的勝利條件是安全格都被揭露。

最後再檢查瀏覽器是 Console 0 errors,首頁和 JavaScript 檔案也都能正常載入。這些證據的角色不同:測試程式證明核心規則,瀏覽器證明使用者真的能操作,Console 和檔案載入證明網頁沒有明顯執行錯誤。

結果:16 passed/0 failed

最終證據:能被支持的完成狀態

最後可以被證據支持的完成狀態是:16 passed/0 failed;三種難度都在瀏覽器中驗收過;第一次點擊安全、插旗不會被自動展開穿透、撞雷失敗、完整勝利、重新開始與計時器都有對應檢查;使用者提出的格子對比問題也經過修正和重新驗證。

這個案例真正值得寫下來的地方,不是「Agent 做了一個踩地雷」而已,而是它展示了交付過程中最容易被忽略的一件事:模型說完成,只是第一步。接下來要用測試、瀏覽器和人工回饋把它一層一層驗清楚,才能知道哪些問題是測試誤判,哪些問題是真的產品缺口,最後哪些狀態是真的有證據支持。

Agent 產出只是起點;當測試、瀏覽器與使用者行為可以互相核對,產出才真正接近可交付。
返回文章列表 回到首頁