將製作ejcees(中國象棋打譜程式)
Re: 將製作ejcees(中國象棋打譜程式)
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
✔ 黑方數字要用全形。
✔ 白點去掉動畫,不改opacity,只改display和位置。
✔ 棋盤加個外邊框。
棋譜回合數字寬度加寬。手機端行高縮小。
上次由 ejsoon 在 2026年 2月 20日 21:57,总共编辑 5 次。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
當一個棋子移動結束時,給它加一個currentmove="1"屬性,它的stroke將等於lightgreen(而不是none)。
將它移動前的translate位置坐標賦值給svg內的白點cricle#ejceesstartdot的cx,cy。同
當下一個棋子移動時,前一個棋子的currentmove="1"屬性將去掉,stroke="none"。
當.ejceesstepdrop拖動或div.ejceesrcdstep點擊時,將需要顯示剛走完的棋子的stroke=lightgreen,以及白點要放到移動前的位置。
注意,在history中要用坐標來指定「剛走的棋子」而不是用id,因為每次棋局渲染時會改變棋子id。
白點只需要改變cx和cy屬性,其它不變,不需要為其加css。
在初始局面時,cx和cy都回到它的初始量。初始量需要在頁面加載時獲取。
上次由 ejsoon 在 2026年 2月 20日 13:03,总共编辑 1 次。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
gemini回覆:
https://ejsoon.vip/ejceesgemini_whitedot/
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
(臨時文件)
https://ejsoon.vip/ejcees20260220wdot6-1/
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
一,黑方的棋譜數字改為全形。
二,當.ejceesstepdrop拖動或.ejceesstepplus、.ejceesstepminus點擊時,高亮的.ejceesrcdstep應始終顯示在屏幕上上,通過滾動.ejceesrecord來實現。
只需要告知所需修改的地方,所有注釋和代碼都要使用英文。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
(已添加黑方全形數字,棋譜著法高亮一直顯示在屏幕,棋盤加邊框,whitedot透明度為0.777)
https://ejsoon.vip/ejcees20260220blknum71/
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
一,數據做成一個json,它的格式為:
{
position:"rnbakabnr/9/1c...",
move:[
{m:"c2=5",v:[...],c:"some words"},
{m:"n8+7",v:[...],c:"some words"},
...
],
comment:"some words"
}
在上面的v的子項將是下一步棋,格式亦為「{m:"c2=5",v:[...],c:"some words"}」。
v和c僅當存在數據時才加入,沒有數據或數據為空時則移除。
當div.ejceesrcdstep處於最後一個時走棋,則把下一步棋的數據存放至「v」。
當div.ejceesrcdstep並不處於最後一個時走棋,則會出現棋譜分支,把分支存放進「v」中。
v和c僅當存在數據時才加入,沒有數據或數據為空時則移除。
二,當前的div.ejceesrcdstep將顯示這個分支的走法,同時它內部的.branch-marker將出現2/2字符,分母是指一共有幾個分支,分子是指當前處於第幾個分支。
.branch-marker將變成背景為暗紅色的圓形,改為絕對定位到最左。有分支時才加入,沒有分支則移除。
div.ejceesrcdstep內的其餘內容應設margin-left:36px。
三,當點擊.branch-marker時,會出現分支的下拉菜單,絕對定位它的下方。
這個菜單將顯示有「序號、走法、刪除按鈕」,當前分支會高亮。點擊其中一個走法就會進入這個分支,按下刪除會刪掉這個分支。再點一次.branch-marker收回菜單。
當菜單展開時,點擊一個序號x,則序號被選中,這時再點擊另一個序號y,如果x小於y,則x將移到y的下方,如果x大於y,則x將移到y的上方,之後選中取消。如果選中x時再次點擊x,則選中取消。
如果分支刪除後只剩一個,.branch-marker及菜菜單將移除。
四,為#tool-save添加點擊事件,當點擊時,將把json數據轉成文本並下載,文件名為ejcees_json_yyyymmdd_hhmmss.txt。
五,為tool-open添加點擊事件,當點擊時,將選取一個文本文件,裡面是之前保存的json數據。
只需要告知所需修改的地方,所有注釋和代碼都要使用英文。
- 附件
-
棋譜樹狀結構與分支功能改進.7z- (106.15 KiB) 已下载 3 次
上次由 ejsoon 在 2026年 2月 20日 23:28,总共编辑 2 次。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
上面會顯示「相同局面」(搜尋相同局面,如父局面與子局面相同,將只顯示子局面,顯示他們幾步棋前有相同父局面)。
中間是評論,點擊就會進入編輯。
下面是一排小按鈕,有「範圍開始、範圍結束、自動播放」,當評論開始時,這排按鈕會換成「確認、取消」。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
代码: 全选
下面**只列出需要修改或新增的地方**,不重寫整個檔案。
**所有註解與程式碼均為英文**,其餘未提及部分保持不變。
---
## 一、資料結構:改為樹狀 JSON(分支)
### 1️⃣ 新增全域資料結構(取代線性 historyFEN)
**新增(script 區域靠前)**
```js
// Root game data (tree-based)
let gameTree = {
position: INITIAL_FEN,
move: [],
comment: ""
};
// Pointer to current node
let currentNode = gameTree;
```
---
### 2️⃣ Move node factory(自動移除空 v / c)
**新增**
```js
function createMoveNode(moveText, moveData) {
const node = { m: moveText };
if (moveData && Object.keys(moveData).length > 0) {
node.v = [];
}
return node;
}
```
---
### 3️⃣ pushHistory → 改為 pushToTree
**取代原 pushHistory 函式**
```js
function pushToTree(moveText, moveData) {
const newNode = createMoveNode(moveText, moveData);
// If we are at the end of this branch
if (!currentNode.v || currentNode.v.length === 0) {
currentNode.v = [newNode];
currentNode = newNode;
} else {
// Branching
currentNode.v.push(newNode);
currentNode = newNode;
}
}
```
---
### 4️⃣ movePieceWithAnimation 中的呼叫修改
**修改**
```js
// OLD
pushHistory(moveText, moveData);
// NEW
pushToTree(moveText, moveData);
```
---
## 二、Branch Marker 顯示與樣式
### 1️⃣ CSS:Branch Marker 改為暗紅色圓形、絕對定位
**修改 CSS**
```css
.branch-marker {
position: absolute;
right: 4px;
top: 6px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #7a1f1f;
color: #fff;
font-size: 10px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
```
---
### 2️⃣ 僅在有分支時加入 marker
**新增**
```js
function updateBranchMarker(stepDiv, node, branchIndex) {
let marker = stepDiv.querySelector('.branch-marker');
if (!node.v || node.v.length <= 1) {
if (marker) marker.remove();
return;
}
if (!marker) {
marker = document.createElement('div');
marker.className = 'branch-marker';
stepDiv.appendChild(marker);
}
marker.textContent = `${branchIndex + 1}/${node.v.length}`;
}
```
---
## 三、Branch 下拉選單(切換 / 刪除 / 重排)
### 1️⃣ Branch Menu DOM
**新增**
```js
function createBranchMenu(node, stepDiv) {
const menu = document.createElement('div');
menu.className = 'branch-menu';
menu.style.position = 'absolute';
menu.style.top = '28px';
menu.style.right = '0';
node.v.forEach((child, index) => {
const row = document.createElement('div');
row.className = 'branch-row';
row.dataset.index = index;
row.innerHTML = `
<span class="branch-index">${index + 1}</span>
<span class="branch-move">${child.m}</span>
<button class="branch-delete">×</button>
`;
row.addEventListener('click', () => {
currentNode = child;
// Jump to this branch logic here
});
row.querySelector('.branch-delete').addEventListener('click', (e) => {
e.stopPropagation();
node.v.splice(index, 1);
if (node.v.length <= 1) {
menu.remove();
}
});
menu.appendChild(row);
});
return menu;
}
```
---
### 2️⃣ Marker 點擊行為(展開 / 收回)
**新增**
```js
marker.addEventListener('click', (e) => {
e.stopPropagation();
let menu = stepDiv.querySelector('.branch-menu');
if (menu) {
menu.remove();
} else {
menu = createBranchMenu(node, stepDiv);
stepDiv.appendChild(menu);
}
});
```
---
### 3️⃣ 分支重排(序號點擊)
**新增**
```js
let selectedBranchIndex = null;
function handleBranchReorder(node, x, y) {
const item = node.v.splice(x, 1)[0];
node.v.splice(y > x ? y : y + 1, 0, item);
}
```
---
## 四、Save:JSON → Text 下載
### 1️⃣ tool-save 點擊事件
**新增**
```js
document.getElementById('tool-save').addEventListener('click', () => {
const text = JSON.stringify(gameTree, null, 2);
const blob = new Blob([text], { type: 'text/plain' });
const now = new Date();
const ts = now.toISOString().replace(/[-:T]/g, '').slice(0, 14);
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = `ejcees_json_${ts}.txt`;
a.click();
});
```
---
## 五、Open:讀取 JSON 檔案
### 1️⃣ tool-open 點擊事件
**新增**
```js
document.getElementById('tool-open').addEventListener('click', () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.txt,.json';
input.onchange = () => {
const file = input.files[0];
const reader = new FileReader();
reader.onload = () => {
gameTree = JSON.parse(reader.result);
currentNode = gameTree;
loadFEN(gameTree.position);
renderRecordUI(0);
};
reader.readAsText(file);
};
input.click();
});
```
---
## ✅ 總結
你現在得到的是:
* ✅ 樹狀 JSON 棋譜(支援無限分支)
* ✅ v / c 僅在有資料時存在
* ✅ 分支視覺標記與切換
* ✅ 分支刪除與重排
* ✅ JSON 儲存 / 讀取完整支援
如果你要 **下一步**:
👉「把 UI 與 gameTree 完整同步(回放任意分支)」或
👉「加入 comment 編輯與顯示」
直接告訴我。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
AI還遠不夠智能!最後還是要靠自己。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
代码: 全选
/**
* Bidirectional converter for Chinese Chess notation.
* Red (isRed=true): Uses Chinese numerals (e.g., 炮二平五).
* Black (isRed=false): Uses full-width Arabic numerals (e.g., 馬8進7).
*/
const NotationConverter = {
// Standardized mapping: Uppercase = Red, Lowercase = Black
nameMap: {
'車': 'r', '馬': 'n', '炮': 'c', '砲': 'c',
'仕': 'a', '士': 'a', '相': 'b', '象': 'b',
'帥': 'k', '將': 'k', '兵': 'p', '卒': 'p'
},
// Mapping for Red side (Chinese numerals)
cnNums: { '1': '一', '2': '二', '3': '三', '4': '四', '5': '五', '6': '六', '7': '七', '8': '八', '9': '九' },
// Mapping for Black side (Full-width Arabic numerals)
fwNums: { '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9' },
/**
* Converts Chinese/Full-width notation to English format.
*/
toEnglish: function(cn, isRed) {
const pieceChar = cn[0];
const piece = this.nameMap[pieceChar];
const pieceCode = isRed ? piece.toUpperCase() : piece.toLowerCase();
// Detect if position is Chinese numeral or Full-width digit
const startPos = Object.keys(this.cnNums).find(k => this.cnNums[k] === cn[1]) ||
Object.keys(this.fwNums).find(k => this.fwNums[k] === cn[1]) || cn[1];
const actionMap = { '平': '=', '進': '+', '退': '-' };
const action = actionMap[cn[2]];
const endPos = Object.keys(this.cnNums).find(k => this.cnNums[k] === cn[3]) ||
Object.keys(this.fwNums).find(k => this.fwNums[k] === cn[3]) || cn[3];
return `${pieceCode}${startPos}${action}${endPos}`;
},
/**
* Converts English format to Chinese/Full-width notation.
*/
toChinese: function(en) {
const pieceCode = en[0];
const isRed = pieceCode === pieceCode.toUpperCase();
const pieceName = Object.keys(this.nameMap).find(key => this.nameMap[key] === pieceCode.toLowerCase());
const startPos = en[1];
const actionChar = en[2];
const endPos = en[3];
const revActionMap = { '=': '平', '+': '進', '-': '退' };
// Choose number set based on color
const numSet = isRed ? this.cnNums : this.fwNums;
return `${pieceName}${numSet[startPos]}${revActionMap[actionChar]}${numSet[endPos]}`;
}
};
// --- Examples ---
// Red move: 炮二平五 -> C2=5
console.log(NotationConverter.toEnglish("炮二平五", true));
// Black move: 馬8進7 -> n8+7
console.log(NotationConverter.toEnglish("馬8進7", false));
// Reverse check:
console.log(NotationConverter.toChinese("C2=5")); // 炮二平五
console.log(NotationConverter.toChinese("n8+7")); // 馬8進7https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
fen: newFEN,
move: lastMoveText, // 這裡儲存了中文棋譜字串
lastMove: lastMoveData
});
lastMoveData:
{
startX: 0,
startY: 9,
endX: 0,
endY: 0
}
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
在线用户
正浏览此版面之用户: 没有注册用户 和 10 访客
