「不能相鄰」規則說到底只是一個欄位間距
這款遊戲每一份規則說明都寫著同一句話:任兩隻貓都不能占用相鄰格子,連對角也不行,每隻貓都會封鎖周圍八格。照字面理解,這代表每放一隻貓,就要檢查八個相鄰格。但真正在遊戲裡擋下不合法移動的驗證邏輯,根本不用做這麼多事,因為 Meowdoku 的棋盤有一個特性,讓八個鄰居裡的大多數,在你檢查任何一欄之前就已經不重要了。
白紙黑字寫的規則
任兩隻貓都不能坐在相鄰的格子裡。這包含跟這隻貓共用一條邊的四格,以及只共用一個角的另外四格,所以一隻新放的貓,除了封鎖自己的列、欄、區塊之外,還會一口氣封鎖八個格子。這個網站上每一份攻略都是這樣描述規則的,因為規則字面上確實是這樣禁止的。
實際上一步一步執行檢查的程式碼,也一樣直白:放下一隻貓後,驗證邏輯會迴圈檢查周圍八個偏移位置,只要其中任何一格已經有貓,就拒絕這次移動。這個迴圈在每一次放置時都會跑一次,這正是值得深究的地方。當只有其中幾格真的處在危險之中時,檢查八格就顯得太多了。
為什麼真正可能擋路的只有一列
先從一個跟「相鄰」完全無關的事實出發:一個有 N 列的棋盤,剛好需要 N 隻貓,而且沒有一列可以放兩隻,所以棋盤解完後,每一列剛好有一隻貓。這其實就是列規則反過來講而已。
「相鄰」是一種距離為一的關係:兩個格子相鄰,代表它們的列差和欄差都必須是 0 或 1。把這個條件跟「每列一隻貓」結合起來,這條規則能觸及的範圍立刻就縮小了。第 2 列的貓和第 5 列的貓相隔三列,不管欄位怎麼配對都不可能相鄰——光是列差就已經超過 ±1 的門檻。唯一有可能相鄰的貓,只會出現在彼此相鄰的兩列之間。
這款遊戲自己的解題器,正是圍繞著這個捷徑寫的。它的限制條件模組把完整解答壓縮成「每列一個欄位數字」,而且直接在自己的註解裡寫出這個化簡:只要保證每列一隻貓,第四條規則就會退化成「相鄰兩列的欄位數字必須差 ≥ 2」——不需要再檢查別的。
上下左右早就已經被別的規則管住了
一隻貓周圍八個相鄰格子中,有四格分別在正上方、正下方、正左方、正右方。這四格都跟這隻貓共用同一列或同一欄——這正是它們算是「正交」而不是「對角」的原因。列規則和欄規則早就禁止在這四格上再放一隻貓,所以這四格不合法,並不是因為相鄰規則,而是因為兩條更簡單的規則早就已經下了判決,相鄰規則只是跟它們得出一樣的結論而已。
四個對角格才是相鄰規則有可能真正提供其他規則沒給的資訊的地方,因為對角鄰居既不跟這隻貓同列、也不跟它同欄。所以「不能相鄰」這條規則真正發揮作用的地方,其實只有四格,不是八格——而且就連這四格,有時候也已經因為另一個不相關的原因而失效:一個對角格剛好跟這隻貓在同一個顏色區塊裡,光靠區塊規則就能把它排除掉。
這裡面到底有多少是真正新增的資訊
在每個難度各四百個新產生的棋盤上,針對解答裡的每一隻貓,檢查它(最多四個)對角鄰居裡,有多少格在相鄰規則出手之前,就已經因為列、欄或區塊而不合法,結果如下:
| 棋盤 | 因列、欄或區塊而早已失效 | 只因相鄰規則而新增的排除 |
|---|---|---|
| 簡單 5×5 | 37% | 63% |
| 普通 7×7 | 44% | 56% |
| 困難 9×9 | 47% | 53% |
| 極難 10×10 | 49% | 51% |
在每個難度下,相鄰規則表面上涵蓋的範圍裡,超過三分之一其實從來沒有真正發揮作用——區塊規則早就已經做出判決了。剩下真正新增的排除,仍然占對角格的多數,但隨著棋盤變大會穩定縮小:從簡單難度的 63%,一路降到極難難度的大約一半。
這個趨勢跟區塊大小有關,而不是相鄰規則本身的問題。棋盤越大,區塊也越大——簡單難度的區塊平均五格,極難難度平均十格——所以在大棋盤上,隨機挑一個對角鄰居,會比在小棋盤上更容易剛好落在這隻貓自己的區塊裡,於是相鄰規則的工作,有更多部分在真正用到之前就已經被區塊規則重複做掉了。
實際測量出來的欄位差距
撐過這一切的規則,最後只剩一個數字:解答裡每一對相鄰列,兩隻貓所在欄位的差距至少要是 2。差距為 2 是規則允許的最緊值——只要再靠近一欄,兩隻貓就會對角相鄰。以下是已解棋盤實際落在這個最小值的頻率:
| 棋盤 | 落在最小合法差距(2)的列數比例 | 平均欄位差距 | 最大可能差距 |
|---|---|---|---|
| 簡單 5×5 | 57.8% | 2.5 | 4 |
| 普通 7×7 | 35.1% | 3.2 | 6 |
| 困難 9×9 | 27.5% | 3.9 | 8 |
| 極難 10×10 | 26.2% | 4.2 | 9 |
在每個難度下,差距恰好為 2 都是單一數值裡出現頻率最高的結果,比其他任何一個差距值都常見,就算在它只佔四分之一左右列數的難度也一樣。而且按定義,這正是完全沒有餘裕的數值:只要任一隻貓再靠近一欄,棋盤就不合法了。
為什麼小棋盤感覺特別緊
相鄰規則在簡單難度咬得最緊,原因純粹是空間不夠。5×5 棋盤只有五欄,卻要把五隻貓分散在兩個相鄰列裡,所以差距為 2 或 3 幾乎涵蓋了所有合法配對——平均差距 2.5,只比最小值高一點點。10×10 棋盤欄數是兩倍,最小差距一樣是 2,所以配對有更多空間可以舒服地遠離這個最小值,平均差距因此爬升到 4.2。
最小值本身從來不會變。從 5×5 開始,任何棋盤大小上,差距為 1 都等於對角相鄰。真正會變的,是棋盤落在這個最小值上的頻率,而這個頻率會隨著棋盤變大、貓有更多欄位可以分散而穩定下降。
這對你在棋盤上實際有什麼幫助
這些發現都不會改變什麼是合法的放置——改變的是你為了檢查一次放置,需要看多少棋盤。別再習慣性掃描一隻新貓周圍全部八個鄰居,改用以下這幾點:
- 只有正上方和正下方那一列重要。 距離你要放置的列有兩列以上的貓,永遠不可能因為相鄰規則而讓這次移動不合法。如果那一列不是相鄰列,就不用花時間管它。
- 在那兩個相鄰列裡,實際上只有兩格有風險。 正上方和正下方的格子早就被欄規則管住了。只有左右兩個對角格,才帶有列規則和欄規則沒給的資訊。
- 差距恰好為 2 是最緊繃的情況,而且很常見。 當相鄰列的貓跟你準備放置的位置只差兩欄時,把它當成一個值得再三確認的臨界情況,而不是罕見的特例——這是每個棋盤大小下最可能出現的差距。
- 區塊規則可能已經先幫你排除掉了。 如果一個對角鄰居剛好跟你的貓同一個顏色區塊,那它早在相鄰規則介入之前就已經不合法——在大棋盤上,大約一半的情況都是如此。
這是怎麼測量出來的
兩張表格都來自遊戲本身的產生器——也就是實際用來產生你玩的棋盤的同一套程式碼,在四個難度下各跑了四百個新棋盤。「因列、欄或區塊而早已失效」指的是這個對角格跟貓在同一個顏色區塊裡——對角格在幾何上不可能跟貓同列或同欄,所以區塊是唯一能在相鄰規則之前就下判決的另一條規則。「最小合法差距」指的是最終解答裡,兩個相鄰列的貓,欄位差恰好是 2。
這些都是目前這個產生器所產生棋盤的特性,而這個產生器過去也曾經被調整過。這篇文章附帶的測試套件,每次執行都會從新產生的棋盤重新推導這兩張表格,所以未來只要區塊大小或欄位配置一改動,就會直接讓建置失敗,而不是讓一個過時的統計數字繼續留在頁面上。
在真正的棋盤上試試這條差距規則
開一個困難 9×9 棋盤,在相鄰兩列放兩隻貓,不要數完兩邊各八個鄰居,只要檢查兩者之間的欄位差就好。差距在 2 以上都合法;差距恰好是 2 的時候,值得再看一眼,因為這是完成棋盤裡最常出現的差距。
棋盤都是在你的瀏覽器裡生成的,你玩的內容不會被傳送到任何地方。