規則

走一枚棋子。它從落點攻擊到的每一個敵方棋子都會加入你方。棋子永遠不會被喫掉,所以 32 枚棋子整局都留在棋盤上;一步攻擊到對方將帥的棋即獲勝。

楚 河 漢 界Mistboard
0 / 1
  1. 紅方走棋。d1 上的車什麼也沒有攻擊。兩個黑卒站在第四橫線上,正是它要去的地方。
  2. 1
  3. 兩個卒都換了陣營。沒有喫子,也沒有棋子離開棋盤,所以一步棋就讓紅方多出兩子、黑方少了兩子。

在演示棋盤上的規則。圓圈標出這步棋轉化的棋子。

停在原地的攻擊不起作用。只有走動的那枚棋子會轉化對方,所以已經瞄着某枚棋子的車必須再走一步才能拿下它。威脅只能靠走棋來製造。

它對象棋做了什麼

永遠沒有殘局。 沒有兌子,局面不會簡化,殘局庫也不可能存在,因爲子力從不減少。象棋的殘局理論,也就是象棋理論的大部分,完全用不上。

炮永遠不會變弱。 象棋的炮需要炮架才能喫子,所以在象棋裏它會隨着棋盤變空而變弱。這裏棋盤從不變空,炮在對局後段和第 3 步時一樣危險。

仕和相什麼也守不住。 它們存在是爲了防喫子,而這裏沒有喫子。它們仍能擋住線路、給炮當炮架,但它們被設計出來要做的事都沒有了。

對局很短,沒有人和棋。 下面 54 盤引擎對局中,一半在第 28 步前結束。沒有一盤是和棋,6,000 盤均勻隨機合法着法的對局也沒有一盤和棋。沒有子力可兌,也沒有殘局可磨,每一盤都會分出勝負。

約 28% 的合法着法當場就輸。 這是引擎對局中 1,696 個局面的平均值。中位局面有 10% 的着法會輸,平均值是由少數非常尖銳的局面拉高的。這個比例從對局前五分之一的 24% 升到最後五分之一的 37%,所以不存在可以安心出子的平靜開局階段。

設計:四個決定

將帥仍然不能照面。 象棋禁止兩個將帥在同一條直線上中間無子相隔,我們保留了這條規則。另一種做法是把白臉將變成勝利條件,但它行不通:只有走動的棋子纔會轉化,所以打開這條線並不能取勝,結果將帥相對而立,對局卻繼續,直到有人把將帥沿着這條線挪一步去領取勝利。

保留這條禁令沒有代價,還帶來了象棋沒有的東西。被釘在將帥線上的棋子無法被移走,因爲這裏沒有任何東西能移走棋子;轉化它也不能解開牽制,因爲轉化是原地變色。你可以贏得這枚棋子,卻仍然動不了它,直到一方的將帥離開這條線。

仕和相受它們所在的區域約束,不論歸誰所有。 被轉化的仕站在敵方九宮裏。如果受原主人的九宮約束,它會永遠凍結在那裏;受它所在的九宮約束,它就能繼續行棋,從內部發動攻擊。從初始局面看兩種理解是一樣的,因爲每個仕都從自己的九宮出發。

兵卒受其主人約束。 兵卒的前進方向必須跟隨它現在的主人,否則被轉化的兵卒會永遠背離新的陣營前進。把這兩條規則弄反,會悄無聲息地毀掉這個遊戲。

和棋需要進度計數。 沒有喫子,幾乎每一步都可以撤回,僅靠三次重複局面不夠。計數在僅有的兩種不可撤回的事件上清零:一次轉化,或一步兵卒走動。

我們如何測試

現有的引擎都下不了這個棋。Pikafish 和 Fairy-Stockfish 都內置了喫子規則,而 Fairy-Stockfish 唯一的轉化機制是像黑白棋那樣翻轉被落子包圍的棋子,那是另一條規則。所以我們用 Rust 寫了一個:帶置換表的 alpha-beta 搜索、主要變例搜索、後期着法縮減,以及針對轉化的靜態搜索。它的子力價值是用邏輯迴歸在自對弈結果上擬合出來的,並在對抗中勝過了我們手工挑選的價值。

我們不公佈擬合出的數值。早先用四分之一數據做的一次擬閤中,有好幾個數值後來符號反轉,這樣的噪聲是一張子力價值表承受不了的。排序保留了下來:仕和相幾乎一文不值,而這本來就可以從無需防守推出。

在測量任何東西之前,先檢查了規則。下面全部 54 盤引擎對局都能在 Mistboard 的 TypeScript 規則內核中重放,1,696 個局面中的每一個都得到相同的轉化和相同數量的合法着法;本頁的每一個棋盤也都經過這個內核。有三個結果不取決於引擎下得多好。

測試結果
均勻隨機合法着法,6,000 局先手方 54.5%,無和棋
從初始局面做證明搜索,208 億節點13 步之內沒有強制勝
當場就輸的合法着法,1,696 個局面平均 28%,中位數 10%

隨機對弈已經偏向先手方。6,000 局中 54.5% 比五五開高出約七個標準誤,所以在雙方都還下不好之前,一步先手就已經有價值。

這個證明需要謹慎,因爲普通搜索做不出證明。後期着法縮減會把靠後的着法搜得更淺,所以普通搜索沒找到勝着,只說明它沒有處處都看到。關閉縮減和靜態搜索,並在殺棋閾值上以是或否來提問,搜索就證明了 13 步之內沒有強制勝。這用了 208 億個節點,約半小時。

我們還檢查了引擎變強時 78% 是否會變化。從每步 30 萬節點到 200 萬節點,七倍的範圍內,它幾乎沒有變化。

僅有穩定還不夠。這項測量的早期版本用六步隨機開局庫來讓對局多樣化,得到 52.7%,並且在十倍的引擎強度範圍內保持不變。它穩定,是因爲開局庫把要測量的那一步先手花掉了:六步隨機着法在兩個引擎走第一步之前就把優勢丟掉了。壞掉的溫度計在每個房間都顯示室溫。78% 不用開局庫,對局的多樣性來自評估抖動。

一步炮定勝負

先手方贏下 78% 的引擎對局,這是從初始局面測得的,不用開局庫,紅黑輪流先走。隨後我們單獨測量了紅方全部 42 個合法的第一步,診斷的樣子變了。

回合紅方得分回合紅方得分回合紅方得分
c1a30.0%h1g325.0%a4a541.7%
e1e20.0%a1a327.1%g4g543.8%
g1i30.0%b3b227.1%b3b445.8%
b3a34.2%h3h229.2%b3b750.0%
b3c38.3%b3d329.2%d1e254.2%
h1i312.5%i4i529.2%e4e554.2%
h3f316.7%b3f333.3%a1a258.3%
b3g318.8%b1a335.4%h3h760.4%
h3c320.8%c1e335.4%h3h460.4%
i1i220.8%b3e335.4%b3b670.8%
h3g322.9%c4c535.4%f1e272.9%
i1i325.0%h3e337.5%h3h579.2%
h3i325.0%h3d339.6%b3b587.5%
g1e325.0%b1c341.7%h3h691.7%
全部 42 個合法的第一步,每個以每步 30 萬節點下 24 盤引擎對局。按每一對列從上往下讀,得分從低到高。

最好的兩步是同一個想法,把炮升到第五或第六橫線:h3h6 得 91.7%,b3b5 得 87.5%。得零分的三步是兩步走到棋盤邊上的相(c1a3 和 g1i3),以及帥從中路上一步(e1e2)。紅方第一步的價值從零到 92% 不等,所以 78% 衡量的是一個總能找到強勢開局的引擎。

楚 河 漢 界Mistboard
0 / 3
  1. 初始局面,紅方走棋。
  2. 1
  3. 炮沿 b 線隔着黑方自己的炮打過去,把 b10 的馬變了過來。它同時威脅 b5e5:以黑方 e7 的卒爲炮架,將就在後面。黑方 38 種應着中有 32 種當場就輸,而 b5e5 對每一種都能取勝。

  4. 1…
  5. 黑方以同樣方式回應,把 h1 的馬變過去。這步看起來很合理,但它就是那 32 種之一。

  6. 2
  7. 炮隔着 e7 的卒打向 e10 的將,對局結束。

紅方勝
從初始局面開始。圓圈標出每步棋轉化的棋子,最後一步標出它攻擊的將。

象棋的炮和目標之間需要正好一枚棋子,而黑方的初始局面免費把這枚棋子擺在了恰好的位置。這個威脅之所以存在,是因爲象棋的初始局面恰好落在本尼迪克特規則能利用的地方。

引擎下的每一盤棋

最強設置下的全部 54 盤對局,每步 200 萬節點,未經挑選。紅方先走 36 盤,贏 33 盤;黑方先走 18 盤,贏 13 盤。先手方贏了 46 盤,輸掉的那 8 盤最值得打開看看。

全部 54 盤對局,每一盤都經規則內核重放。圓圈標出每步棋轉化的棋子,最後一步標出它攻擊的將。用方向鍵逐步瀏覽棋盤上的對局。

餅乾規則

這 42 種開局之間的差距正是這個遊戲可以挽救的原因,而修補辦法已經存在。餅乾規則像兩個孩子分蛋糕:一個切,另一個挑。紅方先走第一步,然後黑方選擇繼續執黑,還是接手紅方的局面。當黑方可以直接拿走最強的開局時,走最強的開局就沒有意義了。

於是紅方被推向最接近均勢的着法,42 步中有四步在那裏。兩步是炮放棄自己的最佳位置,另外兩步是棋盤上最安靜的出子着法。

楚 河 漢 界Mistboard
b3b4,45.8%。炮向前一步,還沒到造成破壞的第五橫線。
楚 河 漢 界Mistboard
b3b7,50.0%。炮一直打進去,立刻轉化,放棄了持續的威脅。
楚 河 漢 界Mistboard
d1e2,54.2%。仕走到九宮中心出子。
楚 河 漢 界Mistboard
e4e5,54.2%。中兵:唯一一步不是敗着的安靜出子着法。

最接近均勢的四個第一步,以及每一步之後紅方的得分。

限定在其中一步上,對局就會接近 50%,因爲紅方再也無法利用這份優勢。六貫棋(Hex)在每種棋盤大小下都被證明是先手勝,卻因爲換邊規則而被競技性地下着。

這四個數字各來自 24 盤對局:不足以在它們之間排名,但足以說明從 0% 到 92% 的差距是真實的。用足夠的樣本確認其中一步能穩定在 50% 附近,是尚待完成的工作。

餅乾規則修正了公平性,而沒有改變尖銳程度。當場就輸的着法比例是規則本身的屬性,所以它不會變。比賽變得均衡,卻依然尖銳;人們是否想下這樣的棋,勝率回答不了。

它目前處於什麼水準

它還不能作爲競技遊戲上線。先手方每四盤贏三盤,任何等級分階梯都撐不住。

不公平不等於不能下。自殺棋已被證明是先手勝,卻每天都有人下,因爲那個證明走的是人類找不到的變化;六貫棋則在換邊規則下照樣被人下。這裏的不同在於深度。這個 78% 依靠的是一步一句話就能說清的棋,把炮升到第五橫線,而引擎每次都能找到它。沒人夠得着的已證勝局只是奇聞;一個能背下來的勝法就是整個遊戲。

餅乾規則之外,還有兩個修補辦法未經測試。把將帥標記出來、給防守方一步應對的機會,可以直接削弱炮的威脅。或者改動初始局面中的中兵,因爲這個威脅之所以存在,只是因爲黑方的卒恰好站在炮需要炮架的位置。

紅方有強制勝嗎?

上面的一切都是勝率,是關於兩個特定引擎的陳述。這個遊戲在完美對弈下是否先手勝,其答案不取決於任何東西下得多好。我們手裏的是一個下界,13 步之內沒有強制勝。這排除了廉價的勝法,而引擎對局中有一半在第 28 步前就結束了。

有兩件事讓這個問題比看起來更難。子力守恆,所以沒有殘局庫可建,正向搜索也沒有可以會合的中點。策略竊取也用不上:棋子只會移動,從不累積,所以先手方不能隨便走一步再把它丟掉。有幫助的是對局短且總能分出勝負,是一棵淺而終局尖銳的樹,而這正是證明數搜索擅長的形狀。

下一級是 14 步。證明可以按紅方 42 個第一步拆分並幾乎無損地並行運行,因爲既然沒有強制勝,任何一個分支都不會剪掉另一個。拆到兩步深,會得到 1,740 個獨立任務,足以用上一個集羣。證明數搜索把精力花在證明樹最窄的部分,馬克·沃特金斯正是用它解決了自殺棋,而我們還沒有實現它。

弱解,或者通過我們沒想到的論證得到的超弱解,也會順帶解決餅乾規則的問題:已被證明的先手勝正是換邊規則被髮明出來要應對的情形。引擎、測試工具、54 盤對局和完整的開局表都在一個代碼倉庫裏。

覈對數據學習象棋