預算有限
聯絡我們 →

唯一解不等於玩得下去a unique answer isn't a solvable puzzle.

在 LinkedIn 玩到 Queens Puzzle,覺得有趣但一天只能玩一次,於是想自己做一個六角形版本。難的不是遊戲,是出題——我做出一堆有唯一解、但沒有人解得開的題目。

這陣子我做了一個 iOS 益智遊戲,叫 Hexhive。

會想做這個的原因是因為在 LinkedIn 玩到了 Queens Puzzle,覺得是挺有趣好玩的,但他一天只能玩一次。

雖然在 app store 裡頭也有類似的遊戲,但是我想一想,為何我不自己做呢?甚至我想進階一點,把它做成六角形的盤面看看會不會更好玩一點。

於是我把這個 idea 跟 Claude Code 討論了一下,提出了「請幫我設計一個六邊形版本的 Queens Puzzle。」的概念

他寫了公式推論後,判斷很容易完成,只要設定有唯一解即可

盤面
邊長 5 的盤面:三個軸方向各一條線,每個色區一個皇冠。

照理講依照 Claude Code 推論的,可以很輕鬆搞定。

理論上啦。

但「理論上」那三個字花了我多少時間。

我以為難的是遊戲,結果難的是出題

規則寫完、能點能放、判定也對了之後,我以為剩下的只是介面。

然後我開始玩之後,發現我很多題解不開。

不是難到需要想很久那種解不開,是推到某一步之後就沒東西可推了——每一格都還有 可能,沒有任何一步是被逼出來的。想繼續只能猜一格,猜錯再退回來。

一開始我以為是我變笨了。後來我讓 Claude Code 跑統計,出來了以下結果:

第一版的出題器出的每一題都是唯一解,而且幾乎每一題都不能玩。

為什麼會這樣

出題的流程大概是這樣:隨機找一組解,繞著皇冠長出顏色區塊,然後不斷調整區塊, 直到盤面只剩一組解。

最後那步是必要的。純隨機長出來的區塊在邊長 4、5 還撞得到唯一解,邊長 6 它試了 三千次,一次都沒有。

問題就出在「不斷調整直到只剩一組解」這句話。

它會把盤面推到「唯一性剛剛好成立」的那條邊界上。而剛剛好唯一,正是最沒有推理 路徑的形狀——答案確實被釘死了,但只是被窮舉釘死的,不是被邏輯逼出來的。人類坐在 那裡看,找不到任何一步是必然的。

我卡在這裡蠻久的,一直在想是不是規則設計本身有問題、是不是六角形不適合這種 玩法。後來才想通,我一直在叫他改錯的東西:

唯一性是「答案」的性質。可玩性是「通往答案那條路」的性質。 我一直在確保前 者,而那件事完全不保證後者。

改成朝「推得動」修補

想通之後解法就浮出來了:既然我要的是「推得動」,那就直接朝那個目標修補,不要 只修到唯一為止。

盤面唯一之後,我讓程式從空盤再跑一次求解,而且只准用人看得懂的規則:

推得完就收下這題。推不完就看它卡在哪:挑最接近被逼出來的那個色區——候選格 最少的那個——把它一格非答案的候選格讓給隔壁區,然後再推一次。

每一輪都把盤面往「推得動」的方向推一點。

我一開始不是這樣做的。我一開始做的是「生成後篩選」:生一題,測簡單規則解不解 得開,解不開就丟掉重生。邊長 6 的通過率大約 0.04%,換算成時間是一題 30 秒。

改成朝目標修補之後,變成一題 56 毫秒。

大約 500 倍。但我要老實說,我做這個改動完全不是為了速度——我是受不了它一直產 出爛題目才改的。速度是因為不再把做出來的東西幾乎全部丟掉,附帶得到的。

然後我發現我把整件事想反了

這是最讓我意外的地方。

如果簡單規則能從空盤一路推到完,那每一個皇冠都是被逼出來的——在那個當下它 是唯一放得下去的格子。而被逼出來的推理鏈不可能分岔。

所以解必然唯一。不用檢查。

程式現在還是會驗一次,但那已經是保險,不是必要條件。而我原本花最多力氣在弄的 那個唯一性修補階段,大部分時候變得可有可無——等盤面變得推得動了,它幾乎總是早 就唯一了。

我把依賴關係整個搞反了好幾週。我以為唯一性是硬條件,可玩性是上面的加分項。

是反過來的。

提示引擎其實是同一個東西

提示
提示不給答案:它標出下一格可以打叉的位置,並說出理由。

決定一題「推不推得動」的那個求解器,跟遊戲裡按提示時跑的是同一個。

這不是為了省事重用——這正是那個保證能成立的原因。出題器只放行提示引擎講得通的 盤面,所以提示引擎永遠有話可說。

提示不會幫你填答案。它會找出下一格可以打叉的位置,標出來,然後告訴你理由是 哪一條規則。

裡面有兩個決定,我覺得比看起來難決定。

規則要按「人看懂的難度」排,不是按威力

一共七條規則,我讓它從最好懂的排到最不好懂的:

  1. 兩個已放的皇冠衝突——同線或同色區
  2. 某個皇冠放在答案不可能有它的位置
  3. 某個色區被關在一條線上
  4. 某條線被關在一個色區裡
  5. 這格放皇冠會讓某個色區或線一格不剩
  6. 這格放下去,往下推會撞到矛盾
  7. 某個色區或線只剩一格——那格是皇冠

「這個色區只剩一格」比任何前瞻都好懂,所以它必須排在前瞻規則之前拿到機會。

我試過按結果型態排,結果是:明明有一句話就能講完的解釋擺在那裡,程式卻給你一段 試誤式的推理。那種提示是正確的,而且沒有用。

第 6 條其實就是試誤法穿了西裝。出題器現在保證題目不需要它——整個測試集裡它一次 都沒觸發過——但我留著當保險。

引擎不採信玩家自己打的叉

玩家會在格子上打叉當筆記。那些叉可能是錯的。

如果提示引擎把它們當事實,它會很開心地從你的錯誤推出一個提示,然後自信地、毫無 幫助地講錯話。

所以引擎維護自己的一組排除集合,只從規則推導出來。你打的叉會被併進去當額外知 識,然後它從那裡繼續往下找——這才是為什麼提示給的一定是「你還沒推出來的下一 步」,而不是你已經走過的那步。

還有一個小決定:推不出東西的時候,它就說推不出來,而且不扣你一次提示。 盤面 沒有必然步通常表示你有個皇冠放錯了,老實說比硬掰一個出來有用。

驗一次它是不是真的成立

我讓程式跑 45 題——邊長 4、5、6 各 15 題——從空盤開始,除了按提示什麼都不做:

平均按幾次提示解完一題:12.5 / 15.4 / 17.7。

最後那組數字我很喜歡。一題需要 15 個必然步才解得完,表示裡面有 15 件事是人找得 到的。那是「這題到底有多少遊戲在裡面」的量度——而它是從同一個求解器掉出來的,我 沒有另外寫東西去算它。

一個比較小的坑,關於提示視窗

順便記一下,因為我用同一種方式錯了兩次。

手機上提示視窗總得出現在某個地方,而盤面已經佔滿螢幕了。

第一次我在遊戲區加了 300px 的底部留白,再把目標格捲進視野。結果是提示打開的瞬 間所有按鈕都跳離拇指,而且收起來之後盤面還停在被捲過的位置。

第二次我量出剩下的空間,把盤面縮小讓位。頁面是不動了,但盤面自己在遊戲中途變大 變小,一樣干擾。

兩次都在試圖「挪出空間」。兩次都動到了玩家正在看的東西。

現在的版本什麼都不挪:面板半透明浮在盤面上,文字後面加一層很淡的模糊——刻意壓 得很淡,因為糊到讓文字舒服的程度,就把「看得到底下」這個目的本身抵銷掉了。

代價是它會蓋住按鈕列幾秒。這個代價比前兩個便宜:5 秒自動收起,按 Esc 或碰一下盤 面也會收。

關於怎麼做的

值得講的不是「AI 幫我寫程式」這件事本身,而是它讓上面那個過程變得可能。出題器 從「生成後篩選」改成「朝目標修補」,中間那些統計、那 45 題的驗證、那些我想錯又 砍掉重來的版本——如果每一輪都要我自己手刻,我大概在「發現題目不能玩」那一步就 放棄了,直接把難度調低當作沒事。

但要往哪個方向修、什麼叫「人看得懂的規則」、規則要怎麼排序,這些沒有人能替 我決定。「唯一性是答案的性質、可玩性是路的性質」這句話不是誰告訴我的,是我卡了 好幾週之後自己想通的。

工具讓我試得夠多次,多到那個想法有機會浮出來。這是我目前對這件事的感覺。

最後

出題器和提示引擎是同一個求解器用了兩次——一次決定一個盤面配不配存在,一次在你玩 的時候解釋它。

Hexhive 出的每一題都能用人腦裝得下的規則推出來,因為那正是它被生出來時必須通過 的條件。

Hexhive 已經上架 App Store:https://apps.apple.com/app/id6799698455

← all entries · 全部文章

let's index something together.

我們聊聊 — 一份你的清單,一份我們的提案。

30 minutes, no slides. Send a brief or a paragraph — we'll come back with three directions and a rough budget within a week.

info@myfundslimited.com · @預算有限公司