Re: 又有一個新的弈棋創意:拚數棋!
代码: 全选
規則更改
被「叉零」封住的,都不算是孤獨數。因為孤獨數的定義是被封在一個小正方形的數,而「叉零」為這個數字增加了四分之一的空間。
介面更改
提子階段也去掉可提子的顯示提示,只需要在點擊到一個不可走到己方「叉零」的棋子時在消息欄給出提示。
當輪到一方時,他的控制區的背景應高亮。
程式更改
把所有棋盤svg的屬性,包括stroke,stroke-width,fill等,都改為寫到svg的內聯屬性中,而不再寫到css中。
回答要求:給出一個python修改代碼的腳本。增加規則:在提子階段,當一方在他的回合中只提了一個「叉零」,則為「孤獨叉」,也要扣分,所扣的分數是後手方在落子階段所剩棋子的數值,對方則加上相應分數。
把棋盤svg的style寫進程式中,其width和height屬性都應是480,在頁面中把100%高寬寫到css。去掉其內部的注釋。
上次由 ejsoon 在 2026年 9月 21日 10:53,总共编辑 3 次。
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
gemini
代码: 全选
針對你設計的這款「拚數棋」,要完全透過 Fairy-Stockfish 的 `variants.ini` 配置文件來完美實現所有規則,需要先了解引擎的技術邊界,並對規則進行技術對接與拆解。
---
### 一、 引擎(Fairy-Stockfish)與介面(GUI/外掛)的技術權責劃分
Fairy-Stockfish 是一個基於 UCI/UGI 協定的「單局棋弈引擎」。它的設計核心是**單局內的合法走法生成與局勢評估**。
1. **`variants.ini` 能幫你做到的部分:**
* 設定 7x7 棋盤與中心點初始擺盤(FEN)。
* 定義 5 種棋子的不同轉向(作為獨立棋子類型)以及各自的移動/提子走法。
* 設定雙方手頭的棋子庫(Pocket)與總量限制(各 25 個)。
* 限制相鄰落子(例如使用 `enclosingDrop = snort` 限制落子不能鄰接特定棋子)。
2. **`variants.ini` 無法單獨實現(需由外部 GUI/裁決程式處理)的部分:**
* **圖論區域與動態分數結算:** 實邊圍成的區域扣分、孤獨數扣分、提子階段的三角形相減累積分數。引擎的核心評估函數(Evaluation)只能預估「盤面優劣」,但遊戲中複雜的區域判分與多階段分數轉化,必須由**外層 GUI / 裁判程式**在局終進行圖論(連通分量/網格圍牆)演算法計算。
* **跨局累計總分(兩局換先後手):** 引擎本身**不具備跨局記憶**。兩局累積總分、互換先後手的邏輯,是由 **GUI(如 CuteChess、PyChess GUI)或賽制平台** 來控制連玩兩局並統計總分。
---
### 二、 Fairy-Stockfish `variants.ini` 設定檔撰寫
你可以將以下內容新增至 Fairy-Stockfish 的 `variants.ini` 中:
```ini
[pinshuqi:fairy]
# 1. 棋盤與基礎規則
boardSize = 7x7
pocketSize = 25
maxMoves = 200
# 2. 落子與提子模式設定
# 允許從手牌中落子 (Drop)
pieceDrops = true
# 限制落子時不能與場上已有棋子的實邊相鄰 (使用 Snort 風格的鄰近限制)
enclosingDrop = snort
# 3. 手牌 (Pocket) 數量限制:雙方各 25 個棋子
# 手牌預設包含所有轉向的棋子,單局總上限各 25 子
pockets = true
# 4. 勝利條件設定
# 以消除對方王將或手牌落盡後結算 (若無王將則以消滅或走盡為終局)
extinctionValue = 0
# 5. 棋子符號與走法定義 (以 Betza 記號法定義提子階段的移動方向)
# -------------------------------------------------------------
# 「單一」(Single): 1實邊1角 -> 前走1步,或兩個斜後方各1步
customPiece1 = s:fW1bF1
# 「雙二」(Double-2): 2分開實邊2角 -> 選擇兩個指定方向走1步
customPiece2 = d:fW1bW1
# 「角二」(Corner-2): 2相連實邊2角 -> 斜向走1步或2步
customPiece3 = c:F1F2
# 「圍三」(Surround-3): 3實邊3角 -> 三個指定方向選一個走1步
customPiece4 = w:fW1lW1rW1
# 「叉零」(Cross-0): 對角線交叉 -> 提子終點 (設定為不可移動或作為固定標記)
customPiece5 = x:
# 6. 棋子不同轉向對映
# 透過字母大小寫與後綴區分不同的方向轉向,GUI 載入時會映射為對應圖片
# N=北, E=東, S=南, W=西
pieceToCharTable = s:s, d:d, c:c, w:w, x:x
```
---
### 三、 兩局統計與計分規則的實現方案
要完全按照你設計的規則遊玩與比賽,建議採用以下架構配合:
1. **單局 AI 算牌(引擎端)**:
* 將上述 `variants.ini` 載入 Fairy-Stockfish。
* 引擎會根據棋子的走法、落子限制與手牌庫進行合法走法搜尋。
2. **區域評分與提子分數(裁判程式/GUI 端)**:
* 撰寫一個輕量級的 Python 腳本(或使用 Custom GUI)監聽引擎輸出的 FEN 碼。
* **落子階段結束時**:腳本執行洪水填充法(Flood Fill)掃描 7x7 棋盤,找出實邊與邊界圍成的區域,計算區域內雙方三角形數量之差、判定孤獨數,並計算出第一階段得分。
* **提子階段**:腳本記錄每一次提子移動(從起點到己方「叉零」的路徑),即時計算三角形數量相減的提子得分。
3. **兩局兩勝/累積總分判決(賽制控制)**:
* 在 CuteChess 或 Python 腳本中設定 **Match 模式**(每輪對局 2 局,第 1 局 Player A 先手,第 2 局 Player B 先手)。
* 第一局結束後記錄玩家 A 與 B 的得分 $S_1(A)$ 與 $S_1(B)$。
* 第二局結束後記錄 $S_2(A)$ 與 $S_2(B)$。
* 最終總分 $Total(A) = S_1(A) + S_2(A)$,總分為正數且高者獲得最終勝利!https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
代码: 全选
<svg id="boardSvg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 480 480" preserveAspectRatio="xMidYMid meet" width="480" height="480" aria-label="Battle Number board" style="display:block;min-width:0;min-height:0;filter:drop-shadow(0 20px 26px rgba(0,0,0,0.27));touch-action:manipulation">
<defs>
<g id="tile0" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc">
<path fill="#c8d2ff" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M-26-26H26"></path>
<path fill="#4965e4" stroke="none" d="M0-12L15.588 15H-15.588Z"></path>
</g>
<g id="tile1" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc">
<path stroke="#ccc" fill="#ffc6bd" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#d54730" d="M-26-26H26"></path>
<path fill="#d54730" stroke="none" d="M0-12L15.588 15H-15.588Z"></path>
</g>
<g id="tile2" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc">
<path fill="#c8d2ff" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M-26 26V-26H26"></path>
<path fill="#4965e4" stroke="none" d="M-16.971-16.971L3.106-11.591-11.591 3.106Z"></path>
<path fill="#4965e4" stroke="none" d="M0 0L20.076 5.38 5.38 20.076Z"></path>
</g>
<g id="tile3" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc">
<path fill="#ffc6bd" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#d54730" d="M-26 26V-26H26"></path>
<path fill="#d54730" stroke="none" d="M-16.971-16.971L3.106-11.591-11.591 3.106Z"></path>
<path fill="#d54730" stroke="none" d="M0 0L20.076 5.38 5.38 20.076Z"></path>
</g>
<g id="tile4" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc">
<path fill="#c8d2ff" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M-26 26V-26M26 26V-26"></path>
<path fill="#4965e4" stroke="none" d="M-18 0L-6-12V12Z"></path>
<path fill="#4965e4" stroke="none" d="M18 0L6-12V12Z"></path>
</g>
<g id="tile5" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc">
<path fill="#ffc6bd" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#d54730" d="M-26 26V-26M26 26V-26"></path>
<path fill="#d54730" stroke="none" d="M-18 0L-6-12V12Z"></path>
<path fill="#d54730" stroke="none" d="M18 0L6-12V12Z"></path>
</g>
<g id="tile6" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc">
<path fill="#c8d2ff" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M-26 26V-26H26V26"></path>
<path fill="#4965e4" stroke="none" d="M-18 12L-6 0V24Z"></path>
<path fill="#4965e4" stroke="none" d="M18 12L6 0V24Z"></path>
<path fill="#4965e4" stroke="none" d="M0-18L12-6H-12Z"></path>
</g>
<g id="tile7" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc">
<path fill="#ffc6bd" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#d54730" d="M-26 26V-26H26V26"></path>
<path fill="#d54730" stroke="none" d="M-18 12L-6 0V24Z"></path>
<path fill="#d54730" stroke="none" d="M18 12L6 0V24Z"></path>
<path fill="#d54730" stroke="none" d="M0-18L12-6H-12Z"></path>
</g>
<g id="tile8" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc" stroke-linecap="round">
<path fill="#c8d2ff" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M-26-26L26 26M-26 26L26-26"></path>
</g>
<g id="tile9" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc" stroke-linecap="round">
<path fill="#ffc6bd" d="M-30-30H30V30H-30Z"></path>
<path fill="none" stroke-width="6" stroke="#d54730" d="M-26-26L26 26M-26 26L26-26"></path>
</g>
<filter id="lastPlacementShadow" x="-50%" y="-50%" width="200%" height="200%" color-interpolation-filters="sRGB">
<feDropShadow dx="0" dy="1" stdDeviation="1" flood-color="#000000" flood-opacity="0.45"></feDropShadow>
</filter>
</defs>
<rect class="board-bg" x="23" y="23" width="434" height="434" rx="14" fill="#fffaf0" stroke="#d8cdb2" stroke-width="3"></rect>
<rect class="board-frame" x="30" y="30" width="420" height="420" fill="none" stroke="#314e4a" stroke-width="3"></rect>
<path class="board-grid" fill="none" stroke="#9e9b90" stroke-width="1.25" d="
M30 90H450 M30 150H450 M30 210H450
M30 270H450 M30 330H450 M30 390H450
M90 30V450 M150 30V450 M210 30V450
M270 30V450 M330 30V450 M390 30V450
"></path>
<circle id="centerDot" class="center-dot" cx="240" cy="240" r="6" fill="#78499b" style="display: none;"></circle>
<g id="pieceLayer" stroke-linecap="round" stroke-linejoin="round">
<use class="board-piece" href="#tile1" xlink:href="#tile1" transform="translate(60 60) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile7" xlink:href="#tile7" transform="translate(120 60) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile5" xlink:href="#tile5" transform="translate(180 60) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile2" xlink:href="#tile2" transform="translate(240 60) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile6" xlink:href="#tile6" transform="translate(300 60) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile5" xlink:href="#tile5" transform="translate(360 60) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile4" xlink:href="#tile4" transform="translate(420 60) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile2" xlink:href="#tile2" transform="translate(60 120) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile1" xlink:href="#tile1" transform="translate(120 120) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile8" xlink:href="#tile8" transform="translate(180 120) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile4" xlink:href="#tile4" transform="translate(240 120) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile1" xlink:href="#tile1" transform="translate(300 120) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile9" xlink:href="#tile9" transform="translate(360 120) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile6" xlink:href="#tile6" transform="translate(420 120) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile6" xlink:href="#tile6" transform="translate(60 180) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile0" xlink:href="#tile0" transform="translate(120 180) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile7" xlink:href="#tile7" transform="translate(180 180) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile8" xlink:href="#tile8" transform="translate(240 180) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile1" xlink:href="#tile1" transform="translate(300 180) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile7" xlink:href="#tile7" transform="translate(360 180) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile0" xlink:href="#tile0" transform="translate(420 180) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile8" xlink:href="#tile8" transform="translate(60 240) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile5" xlink:href="#tile5" transform="translate(120 240) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile9" xlink:href="#tile9" transform="translate(180 240) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile2" xlink:href="#tile2" transform="translate(240 240) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile5" xlink:href="#tile5" transform="translate(300 240) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile8" xlink:href="#tile8" transform="translate(360 240) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile7" xlink:href="#tile7" transform="translate(420 240) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile2" xlink:href="#tile2" transform="translate(60 300) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile3" xlink:href="#tile3" transform="translate(120 300) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile3" xlink:href="#tile3" transform="translate(180 300) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile4" xlink:href="#tile4" transform="translate(240 300) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile0" xlink:href="#tile0" transform="translate(300 300) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile6" xlink:href="#tile6" transform="translate(360 300) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile1" xlink:href="#tile1" transform="translate(420 300) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile7" xlink:href="#tile7" transform="translate(60 360) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile0" xlink:href="#tile0" transform="translate(120 360) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile5" xlink:href="#tile5" transform="translate(180 360) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile2" xlink:href="#tile2" transform="translate(240 360) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile9" xlink:href="#tile9" transform="translate(300 360) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile0" xlink:href="#tile0" transform="translate(360 360) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile3" xlink:href="#tile3" transform="translate(420 360) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile9" xlink:href="#tile9" transform="translate(60 420) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile6" xlink:href="#tile6" transform="translate(120 420) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile4" xlink:href="#tile4" transform="translate(180 420) rotate(90)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile9" xlink:href="#tile9" transform="translate(240 420) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile4" xlink:href="#tile4" transform="translate(300 420) rotate(270)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile3" xlink:href="#tile3" transform="translate(360 420) rotate(180)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
<use class="board-piece" href="#tile8" xlink:href="#tile8" transform="translate(420 420) rotate(0)" pointer-events="none" stroke-linecap="round" stroke-linejoin="round"></use>
</g>
<g id="highlightLayer"></g>
<g id="pathLayer"></g>
<g id="hitLayer">
<rect class="cell-hit" data-index="0" x="30" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="1" x="90" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="2" x="150" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="3" x="210" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="4" x="270" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="5" x="330" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="6" x="390" y="30" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="7" x="30" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="8" x="90" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="9" x="150" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="10" x="210" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="11" x="270" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="12" x="330" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="13" x="390" y="90" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="14" x="30" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="15" x="90" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="16" x="150" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="17" x="210" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="18" x="270" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="19" x="330" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="20" x="390" y="150" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="21" x="30" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="22" x="90" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="23" x="150" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="24" x="210" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="25" x="270" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="26" x="330" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="27" x="390" y="210" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="28" x="30" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="29" x="90" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="30" x="150" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="31" x="210" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="32" x="270" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="33" x="330" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="34" x="390" y="270" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="35" x="30" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="36" x="90" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="37" x="150" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="38" x="210" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="39" x="270" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="40" x="330" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="41" x="390" y="330" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="42" x="30" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="43" x="90" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="44" x="150" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="45" x="210" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="46" x="270" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="47" x="330" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
<rect class="cell-hit" data-index="48" x="390" y="390" width="60" height="60" fill="transparent" cursor="pointer"></rect>
</g>
</svg>https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
battlenumber231.html
新增「孤獨叉」規則,不要再只提一個「叉」了。
把boardSVG的內聯style全部去掉,把所有元素的屬性全寫到內聯中了。
新增「孤獨叉」規則,不要再只提一個「叉」了。
把boardSVG的內聯style全部去掉,把所有元素的屬性全寫到內聯中了。
- 附件
-
battlenumber231.html.7z- (31.64 KiB) 已下载 4 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
之前的規則是:「單一」可朝實邊指向的方向,或朝斜向後方的兩個方向移動。現在改為:把「或朝斜向後方的兩個方向移動」去掉,「單一」將只能朝指向實邊的方向移動。
claude sonnet 5 (medium)
claude sonnet 5 (medium)
代码: 全选
Found both movement functions. I'll remove the two diagonal-backward moves for the「單一」piece in both, and update the rules text.Now let's update the rules text description:All references updated. Let's also check for any other rule-explanation strings (like in-game hint text near piece selection) that might mention this movement.Good, that's the only mention. Now let's do a quick sanity check by opening the file to ensure it's valid (no syntax errors introduced).Syntax is valid. Now let's copy to outputs and present the file.已修改「單一」的移動規則,去掉了斜向後方的兩個移動方向,現在只能朝實邊指向的方向移動。同時更新了兩處移動邏輯程式碼(正式移動與提取路徑計算各一處)以及規則說明文字,三處都保持一致。- 附件
-
battlenumber232.html.7z- (31.22 KiB) 已下载 2 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
修改「規則介紹」文本,連同英文一並更改,不用修改程式邏輯:
claude sonnet 5 (medium)
代码: 全选
修改「規則介紹」文本,連同英文一並更改,不用修改程式邏輯:
把「目標」改為:
雙方比拚多個區域內的數字,數字之差將作為得分。雙方互換先後手玩兩局,總分高者獲勝。
把「棋子」的描述改為:
棋子為正方形,每方共有五種棋子,每種五枚:
單一:一條實邊及一個三角形。
雙二:兩條分開的實邊及兩個三角形。
角二:兩條相連的實邊及兩個三角形。
圍三:三條實邊及三個三角形。
叉零:內部兩條對角線交叉。
每個棋子內的三角形都朝向實邊,但「角二」的兩個三角形會朝向兩條實邊連成的角。
在「落子」中去掉「不必貼合場上已有棋子」。把「先手放完二十五枚棋子,後手放二十四枚」改為「先手必須放完二十五枚棋子,後手必須放二十四枚」。
在「提子」中:
去掉「行動方扣除後手在落子階段未落下棋子的數值,對方取得相同分數」。
把「『單一』只能朝實邊指向的方向移動」改為「『單一』往前走一步」。
去掉「也不能重複提取同一枚棋子」。
全面改寫「計分」:
落子計分:
1.棋子的實邊與棋盤邊界共同把棋盤分成多個區域。
2.在同一個區域像若同時含有雙方棋子,兩方棋子中的三角形數量之差則為得分。
3.如果在同一區域內只含有一方棋子則不計分。
4.如果有一個棋子被困在一個正方形中,則為「孤獨數」,該棋子所屬的一方將按三角形數量扣分,對方取得相應分數。
5.若一個棋子的開口處與一個「叉零」相鄰,則不會成為「孤獨數」,因為多了四分之一格的空間。
6.後手方最後未落下的棋子將視為「孤獨數」並直接扣分。
提子計分:
1.每一個提子回合獨立計分。
2.在所提取的棋子中,己方棋子的三角形數量減去對方棋子的三角形數量,就是該回合的得分。
3.如果本回合只提到本方棋子,則不計分。
4.如果提到了「孤獨叉」,則直接扣分,分值為後手在落子階段最後未落下棋子的數值。
全面改寫「勝負」:
勝負判定:
1.雙方玩兩局,最終分數為正者獲勝。
2.在任意一局中,如果一方不能按規則落子或提子,則直接判負。代码: 全选
Let's view the full rules section (Chinese and English) to make precise edits.Now the 計分 (Chinese) full rewrite:Now the English section — same set of edits, mirrored.Now the English 計分/勝負 full rewrite:Now let's verify no leftover old text and check syntax.All old text removed. Now check JS validity.已完成「規則介紹」的中英文文本修改,程式邏輯未動。
修改內容摘要:
- **目標**:改為新的簡短說明(中英文同步)。
- **棋子**:加入「棋子為正方形」,叉零改為「內部兩條對角線交叉」,並新增三角形朝向實邊(角二例外)的說明。
- **落子**:去掉「不必貼合場上已有棋子」;「放完」改為「必須放完」。
- **提子**:去掉孤獨叉扣分描述、單一移動方向改為「往前走一步」、去掉「不能重複提取同一枚棋子」。
- **計分**:整段改寫為「落子計分」「提子計分」兩組編號條列。
- **勝負**:標題由「勝負與不能行動」改為「勝負」,內容改寫為兩條判定規則。
另外提醒一點:您給的「計分」文本第 2 點原句「在同一個區域像若同時含有雙方棋子」疑似筆誤,我已理解並改成「在同一個區域內若同時含有雙方棋子」,如果原意不同請告訴我再調整。- 附件
-
battlenumber233.html.7z- (31.03 KiB) 已下载 2 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
全面改寫「提子」規則文本,連同英文一並更改,不用改程式邏輯:
提子
落子完畢後,由後手先提子,之後雙方輪流提子,直到各自提完五個「叉零」。
1.每回合任意選擇一枚己方棋子作為起點,包括「叉零」。
2.如果選取的是一枚「非叉零」棋子,按照棋子的三角形朝向移動:「單一」往前走一步;「雙二」選一個方向走一步;「角二」沿斜向走一步或兩步;「圍三」選一個方向走一步。
3.每次必須走到一個棋子上,若在行走方向上有空位,則可越過空位走到該方向上最近的棋子。
4.在一個提子回合中,較早提走的棋子應立即視為空棋位,後續棋子可以越過這些位置。
5.提子路徑必須終止於己方的「叉零」。完成後,移除整條路徑上的所有棋子。
6.如果該回合只提走一枚「叉零」,則這枚棋子為「孤獨叉」。
claude sonnet 5 (medium)
在「3.每次必須走到一個棋子上,若在行走方向上有空位,則可越過空位走到該方向上最近的棋子。」後面加一句「不能走出棋盤邊界。」
提子
落子完畢後,由後手先提子,之後雙方輪流提子,直到各自提完五個「叉零」。
1.每回合任意選擇一枚己方棋子作為起點,包括「叉零」。
2.如果選取的是一枚「非叉零」棋子,按照棋子的三角形朝向移動:「單一」往前走一步;「雙二」選一個方向走一步;「角二」沿斜向走一步或兩步;「圍三」選一個方向走一步。
3.每次必須走到一個棋子上,若在行走方向上有空位,則可越過空位走到該方向上最近的棋子。
4.在一個提子回合中,較早提走的棋子應立即視為空棋位,後續棋子可以越過這些位置。
5.提子路徑必須終止於己方的「叉零」。完成後,移除整條路徑上的所有棋子。
6.如果該回合只提走一枚「叉零」,則這枚棋子為「孤獨叉」。
claude sonnet 5 (medium)
代码: 全选
Now the English section:Duplicate leftover tags remain from the old block. Let me remove them.Now verify JS validity and check rest of file for consistency.Looks clean now. Let's copy to outputs and present.已全面改寫「提子」規則的中英文文本,程式邏輯未動,僅重新編排、重寫敘述順序與內容。代码: 全选
已在中英文版本的第3點後補上「不能走出棋盤邊界」("A move cannot leave the board.")。- 附件
-
battlenumber234.html.7z- (30.97 KiB) 已下载 3 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
MCTS算法需改進,AI是否知道孤獨數會被扣分?AI應盡量使己方的「圍三」不成為孤獨數,盡可能的多得分,少扣分,但也要保證能落下全部棋子。同時也要盡量使對方的棋子成為孤獨數,設法使對方不能落下全部棋子。
在落子階段,MCTS或許不應跑到提子階段,否則會下出很差的棋。不應直接把一個圍三落到不跟其它棋子相鄰的空位上,那樣會直接被封,成為「孤獨數」。
claude sonnet 5 (medium)
在落子階段,MCTS或許不應跑到提子階段,否則會下出很差的棋。不應直接把一個圍三落到不跟其它棋子相鄰的空位上,那樣會直接被封,成為「孤獨數」。
claude sonnet 5 (medium)
代码: 全选
Now update `placementActions` to prefer safe candidates:Now update the `rollout` function to stop before entering the extraction phase when it started in placement, and to lean more on the heuristic during placement:Good, the structure is intact. Now let's validate JS syntax and check whole flow again.Both script blocks (the MCTS worker source and the main app script) parse without syntax errors. Now let's do a quick logical sanity test of the new `createsInstantLonely` and `placementActions` logic in isolation.All test cases behave exactly as expected. Let's also verify `placementActions` correctly avoids risky moves when safe ones exist, and falls back when it must.Confirmed: with safe options available, none of the returned candidates would immediately self-seal. Now test the fallback path (when only risky placements remain) doesn't break and still returns something.Even in a forced-risky scenario, the function correctly falls back to returning the (only) available candidates instead of an empty list. Now let's copy the finished file to outputs and present it.已針對 MCTS 的落子階段決策做了三項改進(都在 worker 內的 AI 搜尋程式碼,未動遊戲規則邏輯):
**1. 新增「即時孤獨數」快速判斷 `createsInstantLonely(board, type, rot, index)`**
只用 O(4) 的方向檢查(棋盤邊界 / 自己的實邊 / 鄰居朝自己的實邊),不必整盤 flood fill,就能判斷把某棋子落在某位置、某個旋轉下,是否會讓這一格「當下立刻」自我封閉成單一格的孤獨數區域。已用多組情境測試驗證,包括你提到的「圍三落在邊緣、開口朝外」的情況會正確被判定為危險,而落在棋盤內部或開口朝向空曠處則正確判定為安全;叉零因三角形值為 0,永遠視為安全。
**2. `placementActions` 優先蒐集安全候選,逼不得已才用危險候選**
產生候選落子時,凡是會讓己方棋子立刻變孤獨數的選項,先放進備用清單;只有在完全沒有安全落點可選時,才會退回使用這些危險候選。這樣 MCTS 的搜尋樹一開始就不會把大量時間浪費在「圍三亂放被秒封」這種明顯壞棋上,也不影響原本的合法性判斷(若真的別無選擇,仍然會回傳可行的落子,不會誤判無棋可下)。
**3. 落子階段的 rollout 不再跑進提子階段**
之前 rollout 會從落子一路模擬到提子結束才評分,但提子過程隨機性很大,等於在「落子好壞」的訊號上疊加大量雜訊。現在只要 rollout 起點是落子階段,一旦落子完成(含後手未落完棋子的孤獨數扣分)就立刻用當下的區域分數評估並結束,不再繼續模擬提子。同時把落子階段「直接比較候選即時分數」的引導比例從 22% 提高到 40%、取樣數從 8 提高到 12(提子階段維持原本比例),讓這個更乾淨的訊號被更充分利用。
這三點合起來的效果:AI 在落子時能更早、更可靠地避免把自己的「圍三」(或其他有三角形的棋子)放進會立刻被封死的空位;同時因為區域分數本來就會對「讓對方棋子變孤獨數」給予正向評分、對「自己棋子變孤獨數」給予負向評分,訊號變乾淨、變強之後,AI 也會更容易主動找到能困住對方棋子的下法。至於「無法落完全部棋子」的情況,原本的搜尋邏輯就已經把「無合法落子」判定為極端的 ±1(直接判負等級),這點不需改動。
我已用 Node.js 對修改後的程式碼做了語法檢查與單元測試(模擬多種棋盤情境呼叫新函式),確認邏輯正確且不影響原有規則判定。由於實際棋力表現最終仍取決於瀏覽器中大量 MCTS 模擬的結果,建議實際開幾局測試手感。- 附件
-
battlenumber235.html.7z- (31.88 KiB) 已下载 2 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
改進MCTS算法
棋盤只有49個格子,應使用bitBoard。
使用增量算法,每種棋子每種旋轉角度可落的地方應保存到一個增量的變量中,在MCTS的搜尋中應使用增量而不要每次都從頭檢查,保證能落下全部棋子。
把落子後使對方的一個棋子成為「孤獨數」作為優先選項。
在落子階段,MCTS不應跑到提子階段,否則會下出很差的棋。
找到方法來提升MCTS的搜尋速度,提升AI的棋力。
回答要求:給出一個修改代碼的python腳本。
棋盤只有49個格子,應使用bitBoard。
使用增量算法,每種棋子每種旋轉角度可落的地方應保存到一個增量的變量中,在MCTS的搜尋中應使用增量而不要每次都從頭檢查,保證能落下全部棋子。
把落子後使對方的一個棋子成為「孤獨數」作為優先選項。
在落子階段,MCTS不應跑到提子階段,否則會下出很差的棋。
找到方法來提升MCTS的搜尋速度,提升AI的棋力。
回答要求:給出一個修改代碼的python腳本。
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
更改邏輯:在一局棋的落子階段,當後手方只剩一個「非叉零」的棋子時,這個棋子將不可被選中和落下。
回答要求:給出修改代碼的python腳本。
https://ejsoon.vip/battlenumber237/
回答要求:給出修改代碼的python腳本。
https://ejsoon.vip/battlenumber237/
- 附件
-
battlenumber237.html.7z- (36.49 KiB) 已下载 2 次
-
battlenumber236.html.7z- (35.98 KiB) 已下载 1 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
AI先手第一手棋應隨機,限制MCTS回合數,增加alpha-beta算法。
代码: 全选
改進:
一,若AI控制的是先手方,則當他落第一手棋的時候,只需隨機選擇角二在棋盤中心放置的四個角度的其中一個。
二,為MCTS的思考限制回合數,簡單AI是2回合,困難AI是3回合,專家AI是4回合,自訂AI是5回合。一回合指的是雙方各下一步棋。自訂AI的思考限制回合數可以在AI設置窗口中調整。但是每步棋仍要保證先手方能落下所有棋子,後手方只剩下一個「非叉零」棋子。
三,加上alpha-beta算法,當在落子階段,前面所限制的回合到達落下的最後一個棋子時,將觸發alpha-beta,思考時間跟原MCTS一樣,當超時仍沒有結論,則會中止並切換回MCTS搜尋。提子階段則一共有五回合,也跟落子階段相同,先是用MCTS搜尋,如果剩餘回合數等於或小於MCTS的限制回合數則觸發alpha-beta。
回答要求:給出修改代碼的python腳本。- 附件
-
battlenumber238.html.7z- (38.78 KiB) 已下载 2 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
在跟AI對弈時發現,AI在算得不夠時,會更大概率的下第一種棋子,說明可下棋子的排序沒有打亂。現在要打亂所下棋子的搜尋,不要每次都先搜尋第一種棋子。
AI應採用增量搜尋,上一回搜尋的結果,仍可用於下一次的搜尋。
AI應採用增量搜尋,上一回搜尋的結果,仍可用於下一次的搜尋。
- 附件
-
battlenumber239.html.7z- (39.55 KiB) 已下载 1 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
把顯示結果的窗口的以下文字說明去掉:
「提子累計分:玩家一 −2,玩家二 +9。一般提子路徑只有包含對方棋子時才計分;若一個回合只提走一枚己方「叉零」,則按孤獨叉規則扣分。表中顯示雙方的零和淨分。」
當AI思考時,在消息欄要顯示是MCTS,還是alpha-beta。
回答要求:給出修改代碼的python腳本。
在顯示「最終結果」的窗口中,第二局應該在第一局的上面,兩局總分要在第二局的上面。兩局總分應採用不同的顯示方式,將總分的數字字體加大。
「提子累計分:玩家一 −2,玩家二 +9。一般提子路徑只有包含對方棋子時才計分;若一個回合只提走一枚己方「叉零」,則按孤獨叉規則扣分。表中顯示雙方的零和淨分。」
當AI思考時,在消息欄要顯示是MCTS,還是alpha-beta。
回答要求:給出修改代碼的python腳本。
在顯示「最終結果」的窗口中,第二局應該在第一局的上面,兩局總分要在第二局的上面。兩局總分應採用不同的顯示方式,將總分的數字字體加大。
- 附件
-
battlenumber242.html.7z- (40.46 KiB) 已下载 1 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
Re: 又有一個新的弈棋創意:拚數棋!
新增導入導出棋譜功能
代码: 全选
新增導入導出棋譜功能
當點擊「導出棋譜」按鈕,將彈出一個窗口,標題為「導入導出棋譜」,下面是「導出棋譜textarea」和「複製」按鈕,其下方是「導入棋譜textarea」和「確認」按鈕。每組textarea跟其右方的按鈕等高。
當打開窗口時,首先清空「導入棋譜textarea」,導出棋譜的textarea會出現當前棋局的棋譜文本,點擊「複製」按鈕則複製這個文本。當「導入棋譜textarea」存在文字時,點擊「確認」按鈕,則會導入棋譜,並關閉窗口。
棋譜格式介紹:
從左到右的横坐標為abcdefg,從上到下的縱坐標為1234567。
「單一」棋子三角形箭頭朝上下左右為hijk;
「雙二」棋子三角形箭頭朝左右為l,朝上下為m;
「角二」棋子三角形箭頭朝左上、右上、右下、左下為nopq;
「圍三」棋子中間三角形箭頭朝上下左右為rstu;
叉零棋子為v。
落子階段每一手棋將用「横坐標+縱坐標+棋子」來表示,用空白隔開。第一手棋將不需要坐標。例如「p a7j b4k」。
如輪到某一方,他因無法合規落子而判負,則在最後加上x。例如「p a7j b4k ... e4u x」
提子階段將只需要用一個或多個坐標相連,不需要棋子,如「c6c4 a4a5a6」。
提子階段將接在落子階段後面,如有第二局將接在第一局後面。
回答要求:給出修改代碼的python腳本。- 附件
-
battlenumber243.html.7z- (45.41 KiB) 尚未被下载
https://ejsoon.vip/
金梭越空:極速暢遊天地
金梭越空:極速暢遊天地
-
- 相似主题
- 回复总数
- 阅读次数
- 最新帖子
在线用户
正浏览此版面之用户: Google [Bot] 和 76 访客