「益智遊戲」和「抽象弈棋」
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

增加功能:當雷腦鼠標或手機觸控按到棋子上不放時,拖動到的象限將使棋子旋轉到那個方向。

claude sonnet 5 (medium)

代码: 全选

Good — I'll add `orientationDrag: null` here, matching the existing transient-UI-state pattern.Now implementing the drag-to-rotate mechanism:Now let's refactor the orientation calculation and add the drag handlers:Now let's wire up the pointer event listeners near the existing click listener for piece frames:Good, `#gameScreen` starts at line 1455 and the piece frames (1460-1634) are inside it. Now let's verify syntax and check for other issues:已加入「按住棋子拖曳到象限即可即時旋轉」的功能,適用於法諾與維諾(可旋轉的棋子;米諾是單格,本來就沒有方向可言)。

實作重點:

1. **共用象限判斷邏輯** `computeQuadrantOrientation`:以按下當下記錄的棋子圖示中心點為基準,判斷指標目前落在左上/右上/右下/左下哪個象限。因為是相對中心點計算,就算拖曳到圖示範圍外,也能正確判斷方向,不會因為拖出邊框就失效。

2. **按下開始拖曳** `handlePieceFramePointerDown`:滑鼠或觸控按到「目前這方正要放置的」法諾或維諾圖示上時,記錄下該圖示當下的位置與指標 ID,並嘗試呼叫 `setPointerCapture`,確保之後拖到圖示外面(甚至到棋盤上)仍能持續追蹤這個指標。

3. **拖曳中即時旋轉** `handleOrientationDragMove`:指標移動時即時重新計算象限,一旦方向改變就更新 `orientationMemory` 並重新渲染棋子圖示與棋盤預覽,讓玩家可以看到棋子隨拖曳即時轉動。

4. **放開手指/滑鼠時定案** `handleOrientationDragEnd`:以放開當下的象限作為最終方向,並清除拖曳狀態、釋放指標捕獲。

5. 這個手勢只會在該棋子正是「目前這方可以放置的棋子」時啟動,不會影響「提前切換階段」或「切回上一階段」等既有的點擊功能;輕點一下(沒有明顯拖曳)也仍然像原本一樣,落在哪個象限就旋轉到哪個方向,行為保持一致。

6. 也加了對應的 CSS:拖曳中的棋子圖示會有明顯的邊框高亮效果,並將可旋轉棋子的 `touch-action` 設為 `none`,避免在手機上拖曳旋轉時被系統誤判成頁面捲動手勢。
附件
vino2252.html.7z
(25.47 KiB) 已下载 7 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

增加導入導出棋譜功能
當點擊「導出棋譜按鈕」時,將彈出一個「導出導入棋譜」窗口。其內容是「導出textarea,複製按鈕,導入textarea,確認按鈕」。每組按鈕都放到相應的textarea的右邊且與其等高。當打開窗口時將為當前局面生成新的棋譜至「導出textarra」,並清空「導入textarea」。當按下「確認」按鈕,將把導入textarea中的棋譜導入到當前局面,包括undo和redo。

棋譜格式為「xyn」或「xyxyxyn(先移動一個米諾再落下一個維諾)或「xyxy0」(飛子),x是横坐標(從左到右從0到9),y是縱坐標(從上二下從0到9)。

n是棋子類型:
法諾朝左上是1
法諾朝右上是2
法諾朝右下是3
法諾朝左下是4
米諾是5
維諾朝左上是6
維諾朝右上是7
維諾朝右下是8
維諾朝左下是9
飛子是0

朝向指的是V形尖角的朝向,坐標也指的是V形尖角的坐標。

每手棋用空格隔開,在前面是雙方輪流行動,但是當有一步出現飛子0之後,則餘下的行動將只是另一方,直到出現第二個飛子0,則本局結束。

本遊戲會有可能比兩局,則第二局的棋譜將直接加在第一局後面。

明確給出所要修改的地方和所要替換的代碼。

代码: 全选

增加導入導出棋譜功能
當點擊「導出棋譜按鈕」時,將彈出一個「導出導入棋譜」窗口。其內容是「導出textarea,複製按鈕,導入textarea,確認按鈕」。每組按鈕都放到相應的textarea的右邊且與其等高。當打開窗口時將為當前局面生成新的棋譜至「導出textarra」,並清空「導入textarea」。當按下「確認」按鈕,將把導入textarea中的棋譜導入到當前局面,包括undo和redo。

棋譜格式為「xyn」或「xyxyxyn(先移動一個米諾再落下一個維諾)或「xyxy0」(飛子),x是横坐標(從左到右從0到9),y是縱坐標(從上二下從0到9)。

n是棋子類型:
法諾朝左上是1
法諾朝右上是2
法諾朝右下是3
法諾朝左下是4
米諾是5
維諾朝左上是6
維諾朝右上是7
維諾朝右下是8
維諾朝左下是9
飛子是0

朝向指的是V形尖角的朝向,坐標也指的是V形尖角的坐標。

每手棋用空格隔開,在前面是雙方輪流行動,但是當有一步出現飛子0之後,則餘下的行動將只是另一方,直到出現第二個飛子0,則本局結束。

本遊戲會有可能比兩局,則第二局的棋譜將直接加在第一局後面。

明確給出所要修改的地方和所要替換的代碼。
https://gpt.quanquan.space/share/Rd3c_i ... eKP9N9l418
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

按以下要求為本遊戲製作MCTS或alpha-beta:

記憶體與物件重用(Memory Reuse)

物件池(Object Pooling):不要在每一次搜尋時 new Node(),預先分配一個 Tree Node Pool,搜尋結束後重置指標(Pointer),徹底避免 GC。

扁平化樹狀結構(Flat Array Tree):將 MCTS 的節點直接儲存在一個大陣列中,用索引(Index)代替物件引用(Reference/Pointer)。

Rollout / Playout(模擬階段)優化

輕量化模擬(Lightweight Rollout):只維護必要的棋盤狀態,不觸發任何完整遊戲邏輯(如 UI 更新、複雜規則檢查)。

啟發式剪枝(Heuristic / Heavy Playout):把能得分且得更高的分的行動排到前面。

RAVE / Rapid Action Value Estimation:利用「全局移動代換」(All-Moves-As-First)假設,讓更新資訊共享給其他相關節點,大幅加快收斂速度。

重用搜尋樹(Tree Reuse):對手落子後,保留原搜尋樹中對應的子樹作為下一輪搜尋的根節點,不重新從頭建立。

動態調整探索常數C:如果舊樹佔用的訪問次數過高(例如根節點已有一萬次訪問),可能導致新展開的節點 UCT 權重被稀釋,可以適度在換根時對舊數據進行衰減(Discounting/Decay),例如將所有舊節點的訪問數與勝場數同比例乘以0.5,讓新搜尋更容易改變舊觀點。

記憶體回收(Garbage Collection):重用子樹時,記得要將未被選中的其他兄弟分支(Sibling Nodes) 的記憶體正確釋放回你的「扁平化陣列(Node Pool)」中,否則搜尋幾十步後池子就會被廢棄節點塞爆。

增量演算法(Incremental Algorithm)。

在 10×10 棋盤中使用 Bitboard

對於 10×10 的棋盤: 100 個格子只需要一個 100-bit 的 BigInt(佔用空間極小)。

在 Bitboard 系統中,為每一種棋子類型維護一個獨立的位元圖(1 代表有棋子,0 代表沒有):
黑方 3 種棋子:black_A, black_B, black_C(3 個 BigInt)
白方 3 種棋子:white_A, white_B, white_C(3 個 BigInt)


當點擊AI控制窗口時,將彈出一個窗口,裡面有AI強度的選擇,每方可選不一樣的強度,右邊是玩家一,左邊是玩家二。控制選項有「人類、簡單、困難、專家、自訂」,每一種選項都有一個相應的svg圖標。

「簡單、困難、專家、自訂」的時間分別是「3s、6s、12s、18s」,下方是時間輸入框,當更改時間時,如果跟前三個預設值不同,則將自動改為自訂。

玩家二默認是簡單AI。

在控制區上加上一個svg圖標,表示當前是人類還是某個AI等級。如果是電腦端,則加在最下方,如果是手機端,則加在最右邊。

明確給出所要修改的地方和所要替換的代碼。

代码: 全选

按以下要求為本遊戲製作MCTS或alpha-beta:
「
記憶體與物件重用(Memory Reuse)

    物件池(Object Pooling):不要在每一次搜尋時 new Node(),預先分配一個 Tree Node Pool,搜尋結束後重置指標(Pointer),徹底避免 GC。

    扁平化樹狀結構(Flat Array Tree):將 MCTS 的節點直接儲存在一個大陣列中,用索引(Index)代替物件引用(Reference/Pointer)。

Rollout / Playout(模擬階段)優化

    輕量化模擬(Lightweight Rollout):只維護必要的棋盤狀態,不觸發任何完整遊戲邏輯(如 UI 更新、複雜規則檢查)。

    啟發式剪枝(Heuristic / Heavy Playout):把能得分且得更高的分的行動排到前面。

RAVE / Rapid Action Value Estimation:利用「全局移動代換」(All-Moves-As-First)假設,讓更新資訊共享給其他相關節點,大幅加快收斂速度。

重用搜尋樹(Tree Reuse):對手落子後,保留原搜尋樹中對應的子樹作為下一輪搜尋的根節點,不重新從頭建立。

動態調整探索常數C:如果舊樹佔用的訪問次數過高(例如根節點已有一萬次訪問),可能導致新展開的節點 UCT 權重被稀釋,可以適度在換根時對舊數據進行衰減(Discounting/Decay),例如將所有舊節點的訪問數與勝場數同比例乘以0.5,讓新搜尋更容易改變舊觀點。

記憶體回收(Garbage Collection):重用子樹時,記得要將未被選中的其他兄弟分支(Sibling Nodes) 的記憶體正確釋放回你的「扁平化陣列(Node Pool)」中,否則搜尋幾十步後池子就會被廢棄節點塞爆。

增量演算法(Incremental Algorithm)。

在 10×10 棋盤中使用 Bitboard 

對於 10×10 的棋盤: 100 個格子只需要一個 100-bit 的 BigInt(佔用空間極小)。

在 Bitboard 系統中,為每一種棋子類型維護一個獨立的位元圖(1 代表有棋子,0 代表沒有):
    黑方 3 種棋子:black_A, black_B, black_C(3 個 BigInt)
    白方 3 種棋子:white_A, white_B, white_C(3 個 BigInt)
」

當點擊AI控制窗口時,將彈出一個窗口,裡面有AI強度的選擇,每方可選不一樣的強度,右邊是玩家一,左邊是玩家二。控制選項有「人類、簡單、困難、專家、自訂」,每一種選項都有一個相應的svg圖標。

「簡單、困難、專家、自訂」的時間分別是「3s、6s、12s、18s」,下方是時間輸入框,當更改時間時,如果跟前三個預設值不同,則將自動改為自訂。

玩家二默認是簡單AI。

在控制區上加上一個svg圖標,表示當前是人類還是某個AI等級。如果是電腦端,則加在最下方,如果是手機端,則加在最右邊。

明確給出所要修改的地方和所要替換的代碼。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

# 角色與目標
你是一位精通遊戲演算法(MCTS, Alpha-Beta, Bitboard)與前端 UI 互動設計的專家。
請根據以下需求,修改並提供可直接替換的程式碼。

---

## 模組一:MCTS / Alpha-Beta 演算法與記憶體優化 (Engine Component)

請實現/優化遊戲核心 AI 搜尋引擎,需嚴格滿足以下技術規範:

### 1. 記憶體與樹結構 (Memory & Tree Structure)
* **Flat Array Tree & Object Pooling**:
- 使用大陣列 (TypedArray / Array) 儲存 MCTS 節點,以索引 (Index) 代替物件引用。
- 預先分配 Node Pool,搜尋結束或換根時重置指標 (Pointer),徹底避免 GC。
* **樹重用 (Tree Reuse) 與記憶體回收**:
- 對手落子後,保留對應子樹作為下一輪搜尋的根節點。
- **必須實現回收機制**:將未被選中的兄弟分支 (Sibling Nodes) 索引歸還給 Node Pool。
* **動態探索常數 (Dynamic C & Decay)**:
- 換根時若舊樹訪問次數過高,對舊數據進行衰減(例如:訪問數與勝場數同比例乘以 0.5)。

### 2. 搜尋與階段切換邏輯 (Search & Phase Logic)
* **Lightweight Rollout**:模擬階段僅維護核心棋盤狀態,嚴禁觸發任何 UI 更新或完整遊戲邏輯。
* **Heuristic / Heavy Playout**:加入啟發式剪枝,優先排序高得分行動。
* **RAVE (Rapid Action Value Estimation)**:實現 All-Moves-As-First (AMAF) 資訊共享機制。
* **Incremental Algorithm**:棋盤狀態更新採用增量式計算。
* **Alpha-Beta 階段搜尋**:
- 當滿足預設的觸發條件時,自動切換至 Alpha-Beta 階段。
- **時間限制規則**:MCTS 階段受設定時間(3s/6s/12s/18s)限制;**一旦進入 Alpha-Beta 階段,立即解除時間限制,直到完全計算出結果為止**。

### 3. 10x10 棋盤 Bitboard 設計
* 使用 100-bit 的 `BigInt` 表示 10×10 棋盤(1 代表有棋子,0 代表無)。
* 維護 6 個獨立的 `BigInt` 位元圖:
- 黑方:`black_A`, `black_B`, `black_C`
- 白方:`white_A`, `white_B`, `white_C`

---

## 模組二:AI 控制彈窗與 UI 互動 (UI & Control Component)

### 1. 選單與預設值
* **控制面板佈局**:
- 點擊 AI 控制區彈出設定視窗。
- 左側為玩家二(預設:**簡單 AI**),右側為玩家一(預設:**人類**)。
- 控制選項:`人類`、`簡單`、`困難`、`專家`、`自訂`(每項均需搭配相應 SVG 圖標)。

* **強度與時間預設映射表**:
強度選項搜尋時間Alpha-Beta 預置觸發條件
**簡單**3 秒有一方用了 3 個維諾
**困難**6 秒有一方用了 2 個維諾
**專家**12 秒有一方用了 1 個維諾
**自訂**18 秒 (預設)有一方用了 3 個米諾 (預設)
* **連動與邊界邏輯**:
- 修改時間輸入框時,若值不等於 3s / 6s / 12s,強度自動切換為「自訂」。
- 觸發條件選項包括:`3個維諾`、`2個維諾`、`1個維諾`、`3個米諾`、`2個米諾`、`1個米諾`。
- **判定邏輯**:若玩家未放置足夠米諾(如未放滿 3 個或 2 個米諾)即跳至維諾階段,等同於觸發「使用了 3 個或 2 個米諾」。

### 2. 當前狀態圖標與實時思考消息框 (Status & Real-time Info Box)
* **圖標顯示**:
- 在控制區顯示代表當前玩家/AI 等級的 SVG 圖標。
- **Desktop (電腦端)**:顯示於最下方;**Mobile (手機端)**:顯示於最右側。
* **實時思考消息框 (Thinking Modal/Toast)**:
- **思考期間(進行中)**:
- MCTS 階段:動態顯示「思考時間(秒)」與「當前搜尋次數(Simulations/Visits)」。
- Alpha-Beta 階段:顯示提示「已進入 Alpha-Beta 終局計算中...(無時間限制)」。
- **思考結束時(結算數據)**:
- 展示最終數據結果:**「總用時」**、**「期望值 (Evaluation Value)」** 及 **「預估勝率 (%)」**。
- **消失邏輯**:若下一回合輪到**人類玩家**操作,思考消息框在展示完整數據後保留 **2 秒**,隨後自動消失;若下一回合仍為 AI 操作,則更新內容並持續顯示。
* **棋盤操作中斷機制 (Interrupt Control)**:
- 當玩家點擊 **「回退 (Undo)」** 或 **「前進 (Redo)」** 時:
1. 立即中斷(Abort)當前正在執行的 AI 思考行程。
2. 關閉思考消息框。
3. 自動將玩家一與玩家二的控制狀態**均強制切換為「人類」**。

---

## 輸出要求
1. **變更說明**:簡要說明修改的檔案與功能模組(例如 Engine、UI Modal、Game Controller)。
2. **替換代碼**:提供完整且可直接複製替換的程式碼,並標註:
- `// === [檔名/組件名] 替換開始 ===`
- `// === [檔名/組件名] 替換結束 ===`

代码: 全选

# 角色與目標
你是一位精通遊戲演算法(MCTS, Alpha-Beta, Bitboard)與前端 UI 互動設計的專家。
請根據以下需求,修改並提供可直接替換的程式碼。

---

## 模組一:MCTS / Alpha-Beta 演算法與記憶體優化 (Engine Component)

請實現/優化遊戲核心 AI 搜尋引擎,需嚴格滿足以下技術規範:

### 1. 記憶體與樹結構 (Memory & Tree Structure)
* **Flat Array Tree & Object Pooling**:
  - 使用大陣列 (TypedArray / Array) 儲存 MCTS 節點,以索引 (Index) 代替物件引用。
  - 預先分配 Node Pool,搜尋結束或換根時重置指標 (Pointer),徹底避免 GC。
* **樹重用 (Tree Reuse) 與記憶體回收**:
  - 對手落子後,保留對應子樹作為下一輪搜尋的根節點。
  - **必須實現回收機制**:將未被選中的兄弟分支 (Sibling Nodes) 索引歸還給 Node Pool。
* **動態探索常數 (Dynamic C & Decay)**:
  - 換根時若舊樹訪問次數過高,對舊數據進行衰減(例如:訪問數與勝場數同比例乘以 0.5)。

### 2. 搜尋與階段切換邏輯 (Search & Phase Logic)
* **Lightweight Rollout**:模擬階段僅維護核心棋盤狀態,嚴禁觸發任何 UI 更新或完整遊戲邏輯。
* **Heuristic / Heavy Playout**:加入啟發式剪枝,優先排序高得分行動。
* **RAVE (Rapid Action Value Estimation)**:實現 All-Moves-As-First (AMAF) 資訊共享機制。
* **Incremental Algorithm**:棋盤狀態更新採用增量式計算。
* **Alpha-Beta 階段搜尋**:
  - 當滿足預設的觸發條件時,自動切換至 Alpha-Beta 階段。
  - **時間限制規則**:MCTS 階段受設定時間(3s/6s/12s/18s)限制;**一旦進入 Alpha-Beta 階段,立即解除時間限制,直到完全計算出結果為止**。

### 3. 10x10 棋盤 Bitboard 設計
* 使用 100-bit 的 `BigInt` 表示 10×10 棋盤(1 代表有棋子,0 代表無)。
* 維護 6 個獨立的 `BigInt` 位元圖:
  - 黑方:`black_A`, `black_B`, `black_C`
  - 白方:`white_A`, `white_B`, `white_C`

---

## 模組二:AI 控制彈窗與 UI 互動 (UI & Control Component)

### 1. 選單與預設值
* **控制面板佈局**:
  - 點擊 AI 控制區彈出設定視窗。
  - 左側為玩家二(預設:**簡單 AI**),右側為玩家一(預設:**人類**)。
  - 控制選項:`人類`、`簡單`、`困難`、`專家`、`自訂`(每項均需搭配相應 SVG 圖標)。

* **強度與時間預設映射表**:

| 強度選項 | 搜尋時間 | Alpha-Beta 預置觸發條件 |
| :--- | :--- | :--- |
| **簡單** | 3 秒 | 有一方用了 3 個維諾 |
| **困難** | 6 秒 | 有一方用了 2 個維諾 |
| **專家** | 12 秒 | 有一方用了 1 個維諾 |
| **自訂** | 18 秒 (預設) | 有一方用了 3 個米諾 (預設) |

* **連動與邊界邏輯**:
  - 修改時間輸入框時,若值不等於 3s / 6s / 12s,強度自動切換為「自訂」。
  - 觸發條件選項包括:`3個維諾`、`2個維諾`、`1個維諾`、`3個米諾`、`2個米諾`、`1個米諾`。
  - **判定邏輯**:若玩家未放置足夠米諾(如未放滿 3 個或 2 個米諾)即跳至維諾階段,等同於觸發「使用了 3 個或 2 個米諾」。

### 2. 當前狀態圖標與實時思考消息框 (Status & Real-time Info Box)
* **圖標顯示**:
  - 在控制區顯示代表當前玩家/AI 等級的 SVG 圖標。
  - **Desktop (電腦端)**:顯示於最下方;**Mobile (手機端)**:顯示於最右側。
* **實時思考消息框 (Thinking Modal/Toast)**:
  - **思考期間(進行中)**:
    - MCTS 階段:動態顯示「思考時間(秒)」與「當前搜尋次數(Simulations/Visits)」。
    - Alpha-Beta 階段:顯示提示「已進入 Alpha-Beta 終局計算中...(無時間限制)」。
  - **思考結束時(結算數據)**:
    - 展示最終數據結果:**「總用時」**、**「期望值 (Evaluation Value)」** 及 **「預估勝率 (%)」**。
    - **消失邏輯**:若下一回合輪到**人類玩家**操作,思考消息框在展示完整數據後保留 **2 秒**,隨後自動消失;若下一回合仍為 AI 操作,則更新內容並持續顯示。
* **棋盤操作中斷機制 (Interrupt Control)**:
  - 當玩家點擊 **「回退 (Undo)」** 或 **「前進 (Redo)」** 時:
    1. 立即中斷(Abort)當前正在執行的 AI 思考行程。
    2. 關閉思考消息框。
    3. 自動將玩家一與玩家二的控制狀態**均強制切換為「人類」**。

---

## 輸出要求
1. **變更說明**:簡要說明修改的檔案與功能模組(例如 Engine、UI Modal、Game Controller)。
2. **替換代碼**:提供完整且可直接複製替換的程式碼,並標註:
   - `// === [檔名/組件名] 替換開始 ===`
   - `// === [檔名/組件名] 替換結束 ===`
附件
vino2253.html.7z
(30.22 KiB) 已下载 6 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

不要加到body後面去啊

代码: 全选

# 角色與目標
你是一位精通遊戲演算法(MCTS, Alpha-Beta, Bitboard)與前端 UI 互動設計的專家。
請根據以下需求,修改並提供可直接替換的程式碼。

---

## 模組一:MCTS / Alpha-Beta 演算法與記憶體優化 (Engine Component)

請實現/優化遊戲核心 AI 搜尋引擎,需嚴格滿足以下技術規範:

### 1. 記憶體與樹結構 (Memory & Tree Structure)
* **Flat Array Tree & Object Pooling**:
  - 使用大陣列 (TypedArray / Array) 儲存 MCTS 節點,以索引 (Index) 代替物件引用。
  - 預先分配 Node Pool,搜尋結束或換根時重置指標 (Pointer),徹底避免 GC。
* **樹重用 (Tree Reuse) 與記憶體回收**:
  - 對手落子後,保留對應子樹作為下一輪搜尋的根節點。
  - **必須實現回收機制**:將未被選中的兄弟分支 (Sibling Nodes) 索引歸還給 Node Pool。
* **動態探索常數 (Dynamic C & Decay)**:
  - 換根時若舊樹訪問次數過高,對舊數據進行衰減(例如:訪問數與勝場數同比例乘以 0.5)。

### 2. 搜尋與階段切換邏輯 (Search & Phase Logic)
* **Lightweight Rollout**:模擬階段僅維護核心棋盤狀態,嚴禁觸發任何 UI 更新或完整遊戲邏輯。
* **Heuristic / Heavy Playout**:加入啟發式剪枝,優先排序高得分行動。
* **RAVE (Rapid Action Value Estimation)**:實現 All-Moves-As-First (AMAF) 資訊共享機制。
* **Incremental Algorithm**:棋盤狀態更新採用增量式計算。
* **Alpha-Beta 階段搜尋**:
  - 當滿足預設的觸發條件時,自動切換至 Alpha-Beta 階段。
  - **時間限制規則**:MCTS 階段受設定時間(3s/6s/12s/18s)限制;**一旦進入 Alpha-Beta 階段,立即解除時間限制,直到完全計算出結果為止**。

### 3. 10x10 棋盤 Bitboard 設計
* 使用 100-bit 的 `BigInt` 表示 10×10 棋盤(1 代表有棋子,0 代表無)。
* 維護 6 個獨立的 `BigInt` 位元圖:
  - 黑方:`black_A`, `black_B`, `black_C`
  - 白方:`white_A`, `white_B`, `white_C`

---

## 模組二:AI 控制彈窗與 UI 互動 (UI & Control Component)

### 1. 選單與預設值
* **控制面板佈局**:
  - 點擊 AI 控制區彈出設定視窗。
  - 左側為玩家二(預設:**簡單 AI**),右側為玩家一(預設:**人類**)。
  - 控制選項:`人類`、`簡單`、`困難`、`專家`、`自訂`(每項均需搭配相應 SVG 圖標)。

* **強度與時間預設映射表**:

| 強度選項 | 搜尋時間 | Alpha-Beta 預置觸發條件 |
| :--- | :--- | :--- |
| **簡單** | 3 秒 | 有一方用了 3 個維諾 |
| **困難** | 6 秒 | 有一方用了 2 個維諾 |
| **專家** | 12 秒 | 有一方用了 1 個維諾 |
| **自訂** | 18 秒 (預設) | 有一方用了 3 個米諾 (預設) |

* **連動與邊界邏輯**:
  - 修改時間輸入框時,若值不等於 3s / 6s / 12s,強度自動切換為「自訂」。
  - 觸發條件選項包括:`3個維諾`、`2個維諾`、`1個維諾`、`3個米諾`、`2個米諾`、`1個米諾`。
  - **判定邏輯**:若玩家未放置足夠米諾(如未放滿 3 個或 2 個米諾)即跳至維諾階段,等同於觸發「使用了 3 個或 2 個米諾」。

### 2. 當前狀態圖標與實時思考消息框 (Status & Real-time Info Box)
* **圖標顯示**:
  - 在控制區顯示代表當前玩家/AI 等級的 SVG 圖標。
  - **Desktop (電腦端)**:顯示於最下方;**Mobile (手機端)**:顯示於最右側。
* **實時思考消息框 (Thinking Modal/Toast)**:
  - **思考期間(進行中)**:
    - MCTS 階段:動態顯示「思考時間(秒)」與「當前搜尋次數(Simulations/Visits)」。
    - Alpha-Beta 階段:顯示提示「已進入 Alpha-Beta 終局計算中...(無時間限制)」。
  - **思考結束時(結算數據)**:
    - 展示最終數據結果:**「總用時」**、**「期望值 (Evaluation Value)」** 及 **「預估勝率 (%)」**。
    - **消失邏輯**:若下一回合輪到**人類玩家**操作,思考消息框在展示完整數據後保留 **2 秒**,隨後自動消失;若下一回合仍為 AI 操作,則更新內容並持續顯示。
* **棋盤操作中斷機制 (Interrupt Control)**:
  - 當玩家點擊 **「回退 (Undo)」** 或 **「前進 (Redo)」** 時:
    1. 立即中斷(Abort)當前正在執行的 AI 思考行程。
    2. 關閉思考消息框。
    3. 自動將玩家一與玩家二的控制狀態**均強制切換為「人類」**。

---

## 輸出要求
**替換代碼**:明確指出所要修改的地方,提供完整且可直接複製替換的程式碼,並標註:
 - `// === 替換開始 ===`
 - `// === 替換結束 ===`
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

vino2256.html
附件
vino2256.html.7z
(47.72 KiB) 已下载 4 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

當前MCTS的搜尋速度極慢,檢查代碼,看看搜尋時都有哪些步驟,為什麼會這麼慢。
vino2265.html.7z
(47.83 KiB) 尚未被下载

代码: 全选

我把 `MCTSEngine`(第 8531 行起)以及它呼叫的核心函式看了一遍,抓出搜尋每一步實際在做什麼,以及慢在哪裡。

## 搜尋的四個階段(`runSimulation()`,8702 行)

1. **Selection(選擇)**:從 root 沿著已展開的樹往下走,每層呼叫 `selectChild()` 用 UCT+RAVE 選子節點。
2. **Expansion(展開)**:走到還沒展開完的節點時,展開一個新子節點。
3. **Rollout(模擬到終局)**:用啟發式挑選最多 80 步(`MAX_SEARCH_PLY`),跑到終局或步數上限。
4. **Backpropagation(回傳)**:把結果沿路徑寫回 `visits` / `value` / RAVE。

問題不在這個框架本身,而在於**第 1、3 步裡反覆呼叫的 `generateCoreActions()`(8215 行)太重,而且完全沒有快取**。

## 主要慢的原因

**1. Selection 階段每次都重算合法走法,沒有快取(影響最大)**

`runSimulation()` 的 selection 迴圈(8711 行)裡:

```js
const actionCount = generateCoreActions(this.workCore, this.actions, this.scores);
```

這一行在**每一層、每一次模擬**都會執行,即使這個節點早就展開完畢、局面完全沒變。也就是說 root(以及其他高訪問次數的節點)在成千上萬次模擬裡,每次都重新跑一次完整的「產生所有候選走法+算啟發值+排序」流程,結果其實每次都一樣。這是典型的「該快取卻沒快取」,直接把有效模擬次數砍掉一大截。

**2. `generateCoreActions` 本身分支數量非常大,尤其是「維諾階段」**

以維諾(vino)階段、且尚未搬動米諾為例(8301–8361 行):
- 直接放置維諾:4 方向 × 100 個錨點 = 400 種
- 「先搬米諾、再放維諾」:最多 3 個米諾 × 4 個方向 × 400(方向+錨點)≈ 最多 4800 種組合
- 若已放過維諾,還會再疊加飛子產生(`generateFlightActions`,100×100=10000 組合)

單一節點光是「維諾階段」就可能要評估幾千到上萬種候選走法。

**3. 每個候選走法的啟發值計算(`actionHeuristic`,8087 行)本身也不便宜**

每次呼叫都會做:
- `quickSquareScore()`:掃過 294 個正方形遮罩 ×2(新舊局面)
- `centerScore()`:掃過 100 格 ×2
- `popcountBigInt()`:逐位元清除迴圈 ×2

單次 `actionHeuristic` 大約要跑 800 次以上的位元運算。乘上第 2 點的候選數量,單次 `generateCoreActions` 在維諾階段可能就要跑上百萬次位元運算。

**4. 這個重量級函式在 Rollout 階段也是每一步都全套重跑**

Rollout 迴圈(8782 行)為了「只從前 12 個候選裡隨機抽一個」,卻還是呼叫同一個 `generateCoreActions()` 產生全部候選+排序,然後才丟棄大部分。而 rollout 最長可以跑 80 步 —— 相當於每次模擬光 rollout 就可能觸發幾十次上面第 2、3 點的昂貴計算。排序(`sortActionsDescending`)也是對全部候選排序,即使只需要前 12 名。

**5. 棋盤用 100 位元的 `BigInt` 表示,所有位元運算都是多字組大數運算**

`black_A/B/C`、`white_A/B/C` 都是 `BigInt`,且超過 64 位元,JS 引擎要用多 limb 的大數運算來處理每一次 `&`、`|`、`^`、比較。這類運算比原生 `Number`/`Uint32Array` 上的位元運算慢非常多(通常一個數量級以上),而且會有額外的記憶體配置與 GC 壓力。因為上面第 2–4 點本來就已經是熱迴圈裡數百萬次的位元運算,用 BigInt 等於是在一個已經很密集的迴圈上再乘上一個很大的常數係數。

## 小結(依影響力排序)

1. Selection 階段對已展開節點重複呼叫 `generateCoreActions`,完全沒快取 → 浪費最嚴重。
2. 「移動米諾+放維諾」與飛子的候選走法組合數本身很大(可到上萬種)。
3. 每個候選都要跑一次不便宜的啟發函式(quickSquareScore/centerScore/popcount)。
4. Rollout 每一步都重跑全套產生+排序,即使只用得到隨機抽出的一個。
5. 底層用 100 位元 BigInt 表示棋盤,讓以上所有熱迴圈裡的位元運算都變慢。

這五點疊加起來,就是「每次模擬」的成本被放大很多倍,導致同樣的搜尋時間預算下,實際能跑的模擬次數非常少,感覺上 MCTS 就特別慢。如果你要,我可以針對第 1 點(節點快取合法走法)先做一版修改,這通常是投報比最高的優化。
針對第 1 點(節點快取合法走法)先做一版修改

代码: 全选

Good, line numbers unchanged (edits were far earlier in the file). Let's view the constructor and `resetTo`/`observeAction` to wire in cache invalidation properly.Now update `MCTSEngine` constructor to create the cache before the pool (so the release callback can close over it), wire up `resetTo`, and add the `getNodeActions` cache helper.Now update `runSimulation`'s selection/expansion loop to use the cache instead of recomputing every visit.Good — no other usage of `this.actions`/`this.scores` in that branch; `selectChild` uses only pool arrays. This part is fine as-is. Now let's verify the file is syntactically valid and re-check all cache-related edits together.Class ends exactly at line 8963. Let's extract lines 6000–8963 for a standalone functional test.Now let's write a functional smoke test that exercises search, tree-reuse (`observeAction`), and reset — the exact paths where the cache must stay correct.Good — the gain is consistent (~65–70%) and grows with tree depth, as expected since more simulations pass through already-cached internal nodes. Let's clean up the test artifacts and finalize the actual deliverable file.## 修改內容

**1. `FlatNodePool` 支援釋放回呼**(8395 行附近)
建構子多一個 `onRelease` 參數;`releaseOne()` 釋放節點索引時會呼叫它。因為節點索引被釋放後會被重新分配給完全不同的局面,所以這是清掉「舊局面走法快取」的唯一正確時機點。

**2. `MCTSEngine` 加上 `actionCache`(Map: node → {actions, count})**
- 建構子先建立 `actionCache`,再用會刪除對應快取的 callback 建立 `pool`。
- `resetTo()` 除了 `pool.reset()`,也 `actionCache.clear()`(整棵樹重來,快取當然要整個清空)。
- 新增 `getNodeActions(node)`:第一次呼叫才真的跑 `generateCoreActions`(含所有候選+啟發值+排序),之後同一節點直接回傳快取的 `Int32Array`。

**3. `runSimulation()` 的 selection/expansion 迴圈改用快取**
把 `generateCoreActions(this.workCore, ...)` 換成 `this.getNodeActions(node)`,同一個節點在同一次 `resetTo` 之後只會真正計算一次。Rollout 階段(模擬到終局那段)維持不變,因為那些局面本來就不屬於樹節點,沒有「重複造訪同一節點」的問題。

## 驗證

因為這段程式碼混在一個會操作 DOM 的大 IIFE 裡,我抽出純運算部分(`CorePosition`/`generateCoreActions`/`FlatNodePool`/`MCTSEngine` 等),搭配一個假的 `document` stub,在 Node.js 下獨立跑:

- **正確性**:跑了 `search → observeAction → search → observeAction → search`(模擬連續下棋時的樹重用)、以及 `resetTo` 到之前局面再搜一次(模擬 undo)。這些流程會不斷釋放並回收節點索引,是最容易讓「快取用到舊局面資料」出包的路徑,全部沒有拋出錯誤,且 `resetTo` 回到同一個局面後的搜尋結果與第一次一致。
- **效能**:從遊戲開局用啟發值排序後取中間值的走法快轉 16 步,進到分支數最大的「維諾階段」,各跑 3 秒與 8 秒的固定時間搜尋比較:

| 情境 | 修改前 | 修改後 |
|---|---|---|
| 3 秒搜尋 | 48.2 次/秒 | 74.1 次/秒(+54%)|
| 8 秒搜尋 | 47.3 次/秒 | 79.1 次/秒(+67%)|

搜尋時間越長(樹越大、節點被重複造訪的次數越多),快取帶來的加速比例越高,這符合預期:這項修改省下的正是「同一個節點被反覆造訪時,重複做同一件事」的浪費。

## 尚未處理的部分

這只解決了上次診斷裡的第 1 點。第 2~5 點(候選走法組合數過大、啟發函式本身昂貴、rollout 每步都重跑全套產生+排序、以及底層用 100 位元 `BigInt`)仍然存在,是接下來如果還要繼續加速可以做的方向,其中又以「用原生 `Number`/`Uint32Array` 取代 100 位元 `BigInt` 棋盤」跟「rollout 用一套更輕量、不需要排序全部候選的走法產生器」影響最大。需要的話我可以接著做。
vino2266.html.7z
(48.42 KiB) 已下载 1 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀一枝独秀
帖子: 6675
注册时间: 2022年 11月 18日 17:36
联系:

Re: 寡人新創作的弈棋「維諾廣場」竟然十分好玩!

帖子 ejsoon »

下面是claude總結的「為何MCTS搜尋會很慢」的理由,其中第一點我已經請它更改。其餘的四點你是否同意?如果同意請給出修改方案。(明確給出所要修改的地方和所要替換的代碼)

https://gpt.quanquan.space/share/e9-MT3 ... sgV7MRXlRE
https://ejsoon.vip/
弈趣極光:享受思維樂趣
回复
  • 相似主题
    回复总数
    阅读次数
    最新帖子

在线用户

正浏览此版面之用户: Google [Bot] 和 13 访客