代码: 全选
以下是將前一個回答中的所有程式碼註釋翻譯為英文的版本,包含 **ICCS 格式修改**、**非 PGN 格式導出邏輯**、**PGN 導入解析器** 以及 **導入按鈕邏輯**:
### 1. Modify `generatePGNFormat` (Support ICCS with Hyphen)
```javascript
function getMoveStr(node, isRed) {
if (oddState === 0) return NotationConverter.toChinese(node.move);
if (oddState === 2) return node.move;
if (oddState === 1 && node.lastMove) {
let dc = node.lastMove;
// Modification: Convert to Uppercase and add hyphen "-", e.g., H2-E2
let start = String.fromCharCode(65 + dc.startX) + (9 - dc.startY);
let end = String.fromCharCode(65 + dc.endX) + (9 - dc.endY);
return (start + "-" + end).toUpperCase();
}
return node.move;
}
```
### 2. Export Logic for Non-PGN Formats (Convert Metadata Tags to Comments)
```javascript
// Helper: Get root comments integrated with Metadata
function getMetaRootComment() {
let metaHeader = "";
pgnMetadata.forEach(m => {
// Only add to comment if the value is not empty and it's not the Result tag
if (m.value && m.value.trim() !== "" && m.name !== "Result") {
metaHeader += `${m.name}:${m.value}\n`;
}
});
let rootC = (historyFEN.c || "").trim();
// Prepend metadata header to the existing root comment
return metaHeader ? (metaHeader + (rootC ? "\n" + rootC : "")) : rootC;
}
// Helper: Append result string to the last move's comment
function appendResultToLastComment(lastNode) {
let resSymbol = pgnMetadata.find(m => m.name === "Result")?.value || "*";
let mapping = { "1-0": "紅勝", "0-1": "黑勝", "1/2-1/2": "平局" };
let resText = mapping[resSymbol] || "";
let existingC = (lastNode.c || "").trim();
if (!resText) return existingC;
// Return existing comment followed by result text
return existingC ? (existingC + "\n" + resText) : resText;
}
```
### 3. PGN Import Logic (`importPGN`)
```javascript
function importPGN(input) {
// 1. Reset current Metadata
pgnMetadata.forEach(m => m.value = (m.name === "Result" ? "*" : ""));
// 2. Parse Tags [Name "Value"]
const tagRegex = /\[(\w+)\s+"([^"]*)"\]/g;
let match;
let lastIndex = 0;
while ((match = tagRegex.exec(input)) !== null) {
let key = match[1], val = match[2];
let metaObj = pgnMetadata.find(m => m.name === key);
if (metaObj) metaObj.value = val;
else pgnMetadata.push({ name: key, value: val });
lastIndex = tagRegex.lastIndex;
}
// 3. Extract the move body (part after all tags)
let body = input.slice(lastIndex).trim();
// Extract the trailing result symbol (1-0, 0-1, 1/2-1/2, *)
const resMatch = body.match(/(1-0|0-1|1\/2-1\/2|\*)$/);
if (resMatch) {
let res = resMatch[1];
let metaObj = pgnMetadata.find(m => m.name === "Result");
if (metaObj) metaObj.value = res;
body = body.slice(0, -res.length).trim();
}
// 4. Parse moves, comments, and branches using a state machine
function parseMoves(str) {
let nodes = [];
let i = 0;
while (i < str.length) {
let char = str[i];
if (char === '{') { // Parse Comment
let end = str.indexOf('}', i);
let comment = str.slice(i + 1, end).trim();
if (nodes.length > 0) nodes[nodes.length - 1].c = comment;
else rootComment = comment; // Comment before the first move
i = end + 1;
} else if (char === '(') { // Parse Branch
let count = 1, j = i + 1;
while (count > 0 && j < str.length) {
if (str[j] === '(') count++;
if (str[j] === ')') count--;
j++;
}
let branchStr = str.slice(i + 1, j - 1);
// Recursively parse the branch and add to the last move's variations
if (nodes.length > 0) nodes[nodes.length - 1].v.push(parseMoves(branchStr)[0]);
i = j;
} else if (/[0-9a-zA-Z\u4e00-\u9fa5]/.test(char)) { // Move notation
let end = str.search(/[\s\(\{\}]/, i);
if (end === -1) end = str.length;
let movePart = str.slice(i, end);
// Exclude move numbers like "1." or "1..."
if (!movePart.includes('.')) {
nodes.push({ move: movePart, c: '', v: [] });
}
i = end;
} else { i++; }
}
return nodes;
}
let rootComment = "";
const moveList = parseMoves(body);
// (Implementation note: Iterate through moveList and use executeMove to rebuild FENs)
return { moves: moveList, rootComment: rootComment };
}
```
### 4. Update `handleConfirm` for PGN Import
```javascript
confirmBtn.addEventListener('click', () => {
const input = textarea.value.trim();
// Check if input starts with the PGN signature
if (input.startsWith('[Game "Chinese Chess"]')) {
// PGN Import Logic
const result = importPGN(input);
// (Need to call applyHistory or a recursive loader here)
alert('PGN Imported successfully');
renderRecordUI();
} else {
// Existing import logic for JSON or DP format
// ...
}
});
```