將製作ejcees(中國象棋打譜程式)
Re: 將製作ejcees(中國象棋打譜程式)
https://ejsoon.vip/wp-content/uploads/2 ... 77741.html
- 附件
-
ejcees20260401moblie99977741.7z- (44.52 KiB) 已下载 3 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
代码: 全选
在上傳的文件中,結合importExportedText和document.getElementById('tool-exp-svg').addEventListener('click', () => {...})這兩個函式,做一個獨立的函式ejceesExpSvg(text)。
首先,在importExportedText函式中,它會接受各種格式的棋譜文本,把它轉換為historyFEN,把這段提取出來,最後把轉換結果console.log。
做一個html+js頁面,來測試ejceesExpSvg(text)函式。裡面需要一個textarae和一個button,以及一個div用來輸出svg。當按下button時執行這個函式。- 附件
-
tmp2.txt- (36.04 KiB) 已下载 5 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
代码: 全选
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>象棋 SVG 轉換測試</title>
<style>
body { font-family: sans-serif; padding: 20px; background: #f0f0f0; }
textarea { width: 100%; height: 150px; margin-bottom: 10px; }
#svg-container { margin-top: 20px; background: white; padding: 10px; border: 1px solid #ccc; min-height: 400px; }
.controls { margin-bottom: 20px; }
</style>
</head>
<body>
<h2>ejceesExpSvg 測試工具</h2>
<textarea id="inputText" placeholder="請貼入 FEN、JSON 或 著法文本 (如: 1. 炮二平五 馬8進7...)"></textarea>
<div class="controls">
<button onclick="handleConvert()">執行 ejceesExpSvg</button>
</div>
<h3>輸出結果:</h3>
<div id="svg-container"></div>
<script>
// --- 模擬原始環境中缺少的輔助變數與函式 ---
let historyFEN = null;
let currentBranch = [];
const moveInterval = 1.5; // [cite: 173]
const moveSpeed = 0.5; //
// 模擬基礎 SVG 模板 (對應原文中的 .ejceespb)
const SVG_TEMPLATE = `
<svg class="ejceespb" viewBox="0 0 432 480" xmlns="http://www.w3.org/2000/svg" style="width:400px">
<rect width="432" height="480" fill="#f9d3a1" />
<g class="etboard"></g>
<g class="etdrop"></g>
</svg>`;
// 模擬字串編碼 [cite: 155]
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode('0x' + p1)));
}
// 模擬座標轉換
function getVisualCoords(x, y) {
return { x: x, y: y };
}
// --- 核心函式:ejceesExpSvg ---
function ejceesExpSvg(text) {
console.log("開始解析文本...");
let movesStr = text.trim();
// 1. 文本標準化
movesStr = movesStr.replace(/车/g, '車').replace(/马/g, '馬').replace(/帅/g, '帥').replace(/将/g, '將').replace(/后/g, '後').replace(/进/g, '進');
// 2. 解析邏輯 (簡化版 importExportedText)
let parsedHistory = null;
if (movesStr.startsWith('{')) {
// 處理 JSON 格式 [cite: 10]
try {
const data = JSON.parse(movesStr);
function expand(node, parentFen) {
let newNode = {
fen: node.fen || parentFen,
move: node.m || null,
lastMove: node.lastMove || null, // 假設已有座標
c: node.c || "",
v: []
};
if (node.v) newNode.v = node.v.map(child => expand(child, newNode.fen));
return newNode;
}
parsedHistory = expand(data, data.fen); [cite: 20]
} catch (e) { console.error("JSON 解析失敗"); }
} else {
// 處理純文本或 FEN [cite: 49, 111]
// 此處簡化為建立一個基礎結構
parsedHistory = { fen: movesStr, v: [], c: "啟始位置" };
}
console.log("解析結果 (historyFEN):", parsedHistory);
historyFEN = parsedHistory;
// 3. SVG 生成邏輯 [cite: 140]
const parser = new DOMParser();
const svgDoc = parser.parseFromString(SVG_TEMPLATE, 'image/svg+xml');
const cloneSvg = svgDoc.querySelector('svg');
cloneSvg.setAttribute('class', 'ejceespbanimate'); [cite: 158]
const etboardClone = cloneSvg.querySelector('.etboard');
const etdropClone = cloneSvg.querySelector('.etdrop');
// 遍歷路徑節點 [cite: 168-172]
let pathNodes = [];
let curr = historyFEN;
while (curr && curr.v && curr.v.length > 0) {
curr = curr.v[0]; // 預設走第一條分支
pathNodes.push(curr);
}
const movedPieceIds = new Set();
const initialCoords = {};
// 生成動畫指令 [cite: 174-188]
pathNodes.forEach((node, i) => {
let stepNum = i + 1;
let moveData = node.lastMove;
if (!moveData) return;
let pieceId = "p" + i; // 模擬 pieceId
movedPieceIds.add(pieceId);
let fromStr = `${moveData.startX * 48 + 24},${moveData.startY * 48 + 24}`;
let toStr = `${moveData.endX * 48 + 24},${moveData.endY * 48 + 24}`;
// 建立 SMIL 動畫
const animT = document.createElementNS('http://www.w3.org/2000/svg', 'animateTransform');
animT.setAttribute('id', `step${stepNum}`);
animT.setAttribute('attributeName', 'transform');
animT.setAttribute('type', 'translate');
animT.setAttribute('from', fromStr);
animT.setAttribute('to', toStr);
animT.setAttribute('dur', `${moveSpeed}s`);
animT.setAttribute('fill', 'freeze');
animT.setAttribute('data-comment', b64EncodeUnicode(node.c || ""));
// 將動畫加入模擬的棋子中 (此處省略具體棋子創建,僅展示邏輯)
console.log(`生成第 ${stepNum} 步動畫: ${fromStr} -> ${toStr}`);
});
// 序列化輸出 [cite: 201]
const svgString = new XMLSerializer().serializeToString(cloneSvg);
return svgString;
}
function handleConvert() {
const text = document.getElementById('inputText').value;
const container = document.getElementById('svg-container');
// 執行函式
const resultSvg = ejceesExpSvg(text);
// 渲染到頁面
container.innerHTML = resultSvg;
}
</script>
</body>
</html>https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
一,在ejceesExpSvg中,缺少的變量都寫到其內部的最前面。
二,在「 return movesStr;」下方是插入節點位置的邏輯,現在去掉這個邏輯,改為如果前面提取到fen局面,則以這個局面為根節點,如果沒有提取到,則以INITIAL_FEN為根節點。
僅需給出所要修改的地方。
- 附件
-
ejceeseExpSvg202604011309.txt- (21.66 KiB) 已下载 5 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
代码: 全选
function ejceesExpSvg(text) {
// --- 內部使用的變量定義 ---
let historyFEN = null;
let currentBranch = [];
let currentStepIndex = 0;
let isRotateEnabled = false;
let isFlipEnabled = false;
let isRangeMode = false;
let rangeStart = null;
let rangeEnd = null;
let isExportTextMode = false;
let isEditingComment = false;
let isEditMode = false;
let isAutoPlaying = false;
const INITIAL_FEN = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1";
const moveInterval = 1.5;
const moveSpeed = 0.5;
// ------------------------
// ... 隨後是 importExportedText 函式定義在 importExportedText 函式內部,找到 return movesStr;(約第 808 行),將其及其下方的「2. Identify the Attach Point」邏輯刪除,替換為以下以 importedFen 或 INITIAL_FEN 為根節點的邏輯 :
代码: 全选
// 刪除原有的 return movesStr; 及其下方的節點查找邏輯
// 2. Identify the Attach Point (Parent Node)
// 改為:以提取到的局面或初始局面作為唯一的根節點
let attachNode = {
fen: importedFen || INITIAL_FEN,
move: null,
lastMove: null,
c: "",
v: []
};
historyFEN = attachNode;
let attachIndex = 0;
currentBranch = [];
currentStepIndex = 0; // 重置當前步數索引
// 3. Process move sequence text (後續邏輯保持不變,將從此根節點開始解析著法)
// ...https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
在「return cloneSvg;」之前,對
jumpToStep(exportStart);
const cloneSvg = document.querySelector('.ejceespb').cloneNode(true);
進行更改。其意義:為先用jumpToStep改變當前局面的svg,然後再賦值給cloneSvg。
在jumpToStep()函式中,改變當前局面的svg要用到loadFEN()和applyLastMoveVisuals(),也要對其更改。
之前的svg是直接寫在頁面上,現在由於要整合進一個js的function中,所以svg不會出現在html頁面上。
僅需給出所要修改的地方。
- 附件
-
ejceeseExpSvg202604011420.txt- (54.46 KiB) 已下载 3 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
代码: 全选
// 1. 你的 SVG 字串變量
const svgString = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="40" fill="red" /></svg>';
// 2. 初始化 DOMParser
const parser = new DOMParser();
// 3. 將字串解析為 XML (SVG 屬於 XML 格式)
const doc = parser.parseFromString(svgString, 'image/svg+xml');
// 4. 取得解析後的 SVG 元素
// parseFromString 會回傳一個完整的 document,我們需要取出它的 root 元素
const clonedSvg = doc.documentElement;
// 現在 clonedSvg 就是一個真正的 DOM 元素,你可以像以前一樣操作它
clonedSvg.style.border = "1px solid black";
document.body.appendChild(clonedSvg);https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 將製作ejcees(中國象棋打譜程式)
3a1k3/4a2R1/9/p1p4c1/8p/2P6/P5P1P/4C4/7r1/2BAKAB2 w - - 0 1
- 附件
-
- Ejcees(3)(1).jpg (42.18 KiB) 查看 38 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
在线用户
正浏览此版面之用户: 没有注册用户 和 13 访客
