Re: 改下哥尼斯堡網頁程式
发表于 : 2026年 4月 13日 21:48
改進:
一,當modal窗口在顯示時,將不會再進行自動搜尋。
二,本棋規則中有「出現重覆局面則判為和棋」,搜尋必殺時應避免和局。
只需給出所要修改的地方。
一,當modal窗口在顯示時,將不會再進行自動搜尋。
二,本棋規則中有「出現重覆局面則判為和棋」,搜尋必殺時應避免和局。
只需給出所要修改的地方。
代码: 全选
這裡為你提供針對這兩項需求的具體修改程式碼片段。請在原始檔案中找到對應區塊進行替換:
### 第一部分:當 modal 顯示時暫停自動搜尋
在 `displayGame()` 函數內,找到自動下棋的邏輯(約在第 442 行附近),加上對 `mcts_modal` 顯示狀態的判斷:
**替換前:**
```javascript
// 自動下棋
clearTimeout(autoPlayTimer);
if (game_status == 1 || game_status == 3) {
let autoBlue = document.getElementById('mcts_auto_blue') && document.getElementById('mcts_auto_blue').checked;
```
**替換後:**
```javascript
// 自動下棋
clearTimeout(autoPlayTimer);
if ((game_status == 1 || game_status == 3) && document.getElementById('mcts_modal').style.display !== 'block') {
let autoBlue = document.getElementById('mcts_auto_blue') && document.getElementById('mcts_auto_blue').checked;
```
---
### 第二部分:在 MCTS 推演中加入「重覆局面則和局」判斷
共需修改三個地方來傳遞與檢查歷史紀錄 (`game_history`)。
**1. 展開 `rootState` 時拷貝當下歷史(約在 `runMCTS` 內第 746 行附近)**
**替換前:**
```javascript
let rootState = {
p0: parseInt(men_bottom[0].getAttribute("i") || men_top[0].getAttribute("i")),
p1: parseInt(men_bottom[1].getAttribute("i") || men_top[1].getAttribute("i")),
turn: current_man,
empty_map: JSON.parse(JSON.stringify(empty_map)),
arrow_map: JSON.parse(JSON.stringify(arrow_map)),
stack_arrow: stack_arrow.slice()
};
```
**替換後:**
```javascript
let rootState = {
p0: parseInt(men_bottom[0].getAttribute("i") || men_top[0].getAttribute("i")),
p1: parseInt(men_bottom[1].getAttribute("i") || men_top[1].getAttribute("i")),
turn: current_man,
empty_map: JSON.parse(JSON.stringify(empty_map)),
arrow_map: JSON.parse(JSON.stringify(arrow_map)),
stack_arrow: stack_arrow.slice(),
history: game_history.slice() // 拷貝歷史紀錄以供檢查和局
};
```
**2. 在 `applyMove` 中傳遞歷史陣列(約第 930 行附近)**
**替換前:**
```javascript
// 將某條路徑套用到當前狀態,翻轉橋樑,並判斷是否立刻分出勝負
function applyMove(state, route) {
let nextState = {
p0: state.p0,
p1: state.p1,
turn: 1 - state.turn,
empty_map: JSON.parse(JSON.stringify(state.empty_map)),
arrow_map: JSON.parse(JSON.stringify(state.arrow_map)),
stack_arrow: state.stack_arrow.slice()
};
```
**替換後:**
```javascript
// 將某條路徑套用到當前狀態,翻轉橋樑,並判斷是否立刻分出勝負
function applyMove(state, route) {
let nextState = {
p0: state.p0,
p1: state.p1,
turn: 1 - state.turn,
empty_map: JSON.parse(JSON.stringify(state.empty_map)),
arrow_map: JSON.parse(JSON.stringify(state.arrow_map)),
stack_arrow: state.stack_arrow.slice(),
history: state.history ? state.history.slice() : [] // 傳遞並拷貝推演歷史
};
```
**3. 在 `applyMove` 更新完位置後加入和局判定(約第 966 行附近)**
**替換前:**
```javascript
// 更新位置
if (state.turn === 0) nextState.p0 = route[route.length - 1];
else nextState.p1 = route[route.length - 1];
// 檢查對手是否能射擊你 (BFS 尋找連通性)
let target = state.turn === 0 ? nextState.p0 : nextState.p1;
```
**替換後:**
```javascript
// 更新位置
if (state.turn === 0) nextState.p0 = route[route.length - 1];
else nextState.p1 = route[route.length - 1];
// 檢查是否出現重覆局面 (和局)
let state_hash = JSON.stringify([nextState.p0, nextState.p1].concat(nextState.stack_arrow));
if (nextState.history.includes(state_hash)) {
return {
terminal: true,
winner: -1 // 回傳 -1 代表和局,MCTS 必殺判斷與 Playout 都會以此避開無窮迴圈
};
}
nextState.history.push(state_hash);
// 檢查對手是否能射擊你 (BFS 尋找連通性)
let target = state.turn === 0 ? nextState.p0 : nextState.p1;
```