將製作ejcees(中國象棋打譜程式)

分享和讨论Javascript相关的话题
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

simulateMove(fen, startX, startY, endX, endY)

代码: 全选

/**
 * Simulates a move based on coordinates and returns the new FEN string.
 * @param {string} fen - The current FEN string before the move.
 * @param {number} startX - The starting X coordinate (0-8).
 * @param {number} startY - The starting Y coordinate (0-9).
 * @param {number} endX - The target X coordinate (0-8).
 * @param {number} endY - The target Y coordinate (0-9).
 * @returns {string} The new FEN string after the move.
 */
function simulateMove(fen, startX, startY, endX, endY) {
    const parts = fen.split(' ');
    const boardPart = parts[0];
    let turn = parts[1] || 'w';

    // 1. Initialize an empty 10x9 board (y: 0-9, x: 0-8)
    const board = Array.from({ length: 10 }, () => Array(9).fill(''));

    // 2. Parse the current FEN to populate the board array
    const rows = boardPart.split('/');
    rows.forEach((row, y) => {
        let x = 0;
        for (let i = 0; i < row.length; i++) {
            const char = row[i];
            if (/[0-9]/.test(char)) {
                // If it's a number, skip that many empty squares
                x += parseInt(char, 10);
            } else {
                // If it's a letter (piece), place it on the board
                board[y][x] = char;
                x++;
            }
        }
    });

    // 3. Extract the moving piece
    const piece = board[startY][startX];
    
    // Safety check: ensure there is actually a piece to move
    if (!piece) {
        console.warn(`simulateMove: No piece found at (${startX}, ${startY})`);
        return fen; 
    }

    // 4. Apply the move (remove from start, place at end)
    board[startY][startX] = '';
    board[endY][endX] = piece; // This automatically overwrites (captures) any existing piece

    // 5. Toggle the turn ('w' -> 'b', 'b' -> 'w')
    turn = (turn === 'w') ? 'b' : 'w';

    // 6. Generate the new FEN string from the updated board array
    let newFenBoard = '';
    for (let y = 0; y <= 9; y++) {
        let emptyCount = 0;
        for (let x = 0; x <= 8; x++) {
            if (board[y][x] === '') {
                emptyCount++;
            } else {
                if (emptyCount > 0) {
                    newFenBoard += emptyCount;
                    emptyCount = 0;
                }
                newFenBoard += board[y][x];
            }
        }
        // Append any remaining empty spaces at the end of the row
        if (emptyCount > 0) {
            newFenBoard += emptyCount;
        }
        // Add row separator, except for the last row
        if (y < 9) {
            newFenBoard += '/';
        }
    }

    // Return the combined FEN string
    return `${newFenBoard} ${turn}`;
}
deriveCoordsFromMove

代码: 全选

/**
 * Derives start and end coordinates from a FEN string and move notation.
 * Handles complex notations like "+C=5", "3p+1", and "+3=7".
 * * @param {string} fen - The FEN string before the move.
 * @param {string} move - The move notation (e.g., "C2=5", "+n+8", "3p+1").
 * @param {boolean} [isRed] - Optional flag indicating if it's Red's turn. 
 * If not provided, it parses it from the FEN string.
 * @returns {Object} An object containing { startX, startY, endX, endY }.
 */
function deriveCoordsFromMove(fen, move, isRed) {
    // Determine player color from FEN if not explicitly provided
    if (typeof isRed === 'undefined') {
        isRed = fen.includes(' w');
    }

    // 1. Parse the board from FEN to extract piece coordinates
    const boardPart = fen.split(' ')[0];
    const rows = boardPart.split('/');
    let myPieces = [];

    rows.forEach((row, y) => {
        let x = 0;
        for (let i = 0; i < row.length; i++) {
            const char = row[i];
            if (/[0-9]/.test(char)) {
                // Skip empty squares
                x += parseInt(char, 10);
            } else {
                // Check if the piece belongs to the current player
                const pieceIsRed = (char >= 'A' && char <= 'Z');
                if (pieceIsRed === isRed) {
                    myPieces.push({ char, x, y });
                }
                x++;
            }
        }
    });

    // 2. Dissect the 4-character move notation
    const char1 = move.charAt(0);
    const char2 = move.charAt(1);
    const action = move.charAt(2);
    const val = parseInt(move.slice(3), 10);

    let startX = -1;
    let startY = -1;
    let pieceType = '';

    /**
     * Helper to select the correct piece based on prefix (+, -, =, 1, 2, 3...)
     * Assumes the array is sorted from "Front" to "Back".
     */
    const getPieceFromPrefix = (piecesInCol, prefix) => {
        if (prefix === '+') return piecesInCol[0];
        if (prefix === '-') return piecesInCol[piecesInCol.length - 1];
        if (prefix === '=') return piecesInCol[1]; // Middle piece of 3
        const num = parseInt(prefix, 10);
        if (!isNaN(num) && num > 0) return piecesInCol[num - 1];
        return piecesInCol[0]; // Fallback
    };

    // 3. Identify the moving piece and its starting coordinates
    if (/[a-zA-Z]/.test(char1) && /[0-9]/.test(char2)) {
        // Case 1: Standard Notation (e.g., "C2=5", "P3+1", "n8+7")
        pieceType = isRed ? char1.toUpperCase() : char1.toLowerCase();
        const startCol = parseInt(char2, 10);
        startX = isRed ? (9 - startCol) : (startCol - 1);
        
        const candidate = myPieces.find(p => p.char === pieceType && p.x === startX);
        if (candidate) {
            startY = candidate.y;
        }
    } 
    else if (/[\+\-\=12345]/.test(char1) && /[a-zA-Z]/.test(char2)) {
        // Case 2: Prefix + Piece Notation (e.g., "+C=5", "-n+8")
        pieceType = isRed ? char2.toUpperCase() : char2.toLowerCase();
        
        // Group pieces of this specific type by column
        const typePieces = myPieces.filter(p => p.char === pieceType);
        const colGroups = {};
        typePieces.forEach(p => {
            if (!colGroups[p.x]) colGroups[p.x] = [];
            colGroups[p.x].push(p);
        });
        
        // Find the column that actually has multiple pieces of this type
        let targetGroup = null;
        for (let x in colGroups) {
            if (colGroups[x].length > 1) {
                targetGroup = colGroups[x];
                break; // Usually only one column meets this criteria (except for pawns)
            }
        }
        
        if (targetGroup) {
            // Sort Front to Back: Red Front is smaller Y, Black Front is larger Y
            targetGroup.sort((a, b) => isRed ? (a.y - b.y) : (b.y - a.y));
            const candidate = getPieceFromPrefix(targetGroup, char1);
            if (candidate) {
                startX = candidate.x;
                startY = candidate.y;
            }
        }
    }
    else if (/[\+\-\=12345]/.test(char1) && /[0-9]/.test(char2)) {
        // Case 3: Prefix + Column Notation specifically for Pawns (e.g., "+3=4", "25+1")
        pieceType = isRed ? 'P' : 'p';
        const startCol = parseInt(char2, 10);
        startX = isRed ? (9 - startCol) : (startCol - 1);
        
        // Extract all pawns located on this specific column
        const targetGroup = myPieces.filter(p => p.char === pieceType && p.x === startX);
        if (targetGroup.length > 1) {
            // Sort Front to Back
            targetGroup.sort((a, b) => isRed ? (a.y - b.y) : (b.y - a.y));
            const candidate = getPieceFromPrefix(targetGroup, char1);
            if (candidate) {
                startY = candidate.y;
            }
        }
    }

    // Safety check if notation parsing failed
    if (startX === -1 || startY === -1) {
        console.error("Failed to derive start coordinates for move:", move);
        return null; 
    }

    // 4. Calculate target coordinates (endX, endY)
    let endX = -1;
    let endY = -1;
    
    // Some pieces use the `val` to represent the target column instead of step count
    const valIsEndCol = ['n', 'N', 'b', 'B', 'a', 'A', 'k', 'K'].includes(pieceType);

    if (action === '=') {
        // Horizontal move: Y stays the same, X is directly derived from the target column
        endX = isRed ? (9 - val) : (val - 1);
        endY = startY;
    } else {
        // Vertical or Diagonal move ('+' or '-')
        // Direction multiplier: For Red, '+' means moving up (-Y). For Black, '+' means moving down (+Y).
        const dir = isRed ? (action === '+' ? -1 : 1) : (action === '+' ? 1 : -1);
        
        if (valIsEndCol) {
            // For Knights, Elephants, Advisors, and King: The value indicates the target column
            endX = isRed ? (9 - val) : (val - 1);
            const dx = Math.abs(endX - startX);
            let dy = 0;
            
            const lowerType = pieceType.toLowerCase();
            if (lowerType === 'n') {
                dy = (dx === 1) ? 2 : 1; // Knight moves in 1x2 or 2x1 L-shape
            } else if (lowerType === 'b') {
                dy = 2; // Elephant moves 2x2 diagonally
            } else if (lowerType === 'a' || lowerType === 'k') {
                dy = 1; // Advisor moves 1x1 diagonally, King moves 1 step vertically
            }
            
            endY = startY + dir * dy;
        } else {
            // For linear pieces (Chariot, Cannon, Pawn): The value represents the number of steps
            endX = startX;
            const steps = val;
            endY = startY + dir * steps;
        }
    }

    return { startX, startY, endX, endY };
}
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

(臨時文件)https://ejsoon.vip/wp-content/uploads/2 ... ds954.html

需要修複:當只有一列兵或卒時,仍要用「前卒、後卒」,而當這一列兵或卒的數量超過三個時,其處於中間的兵或卒將用「二兵、三兵、四兵」來描述。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

修正當四個或五個兵卒在同一列時,不能用「前兵平二」的問題。

代码: 全选

在function getMoveNotation中,以下這段代碼需要修正:

                    // --- KEY FIX: Check for ambiguity across different columns ---
                    if (isPawn && multiPawnCols.length > 1 && prefix !== '=') {
                        // If more than one column has multiple pawns, use Column Number instead of "Pawn"
                        location = startCol;
                    } else {
                        location = name;

即使有多個兵或卒在同一列,最前面的仍然要用「+」,最後面的仍然要用「-」。

            function getMoveNotation(pieceId, startX, startY, endX, endY, capturedId) {
                const char = pieceId[0];
                const isRed = (char === char.toUpperCase());
                const startCol = isRed ? (9 - startX) : (startX + 1);
                const endCol = isRed ? (9 - endX) : (endX + 1);
                const isPawn = char.toLowerCase() === 'p';

                // 1. Find all friendly pieces of the same type
                const samePieces = [];
                for (const [pos, id] of tileMap.entries()) {
                    if (id.startsWith(char)) {
                        const [px, py] = pos.split(',').map(Number);
                        samePieces.push({
                            id,
                            x: px,
                            y: py
                        });
                    }
                }

                // 2. Identify if multiple columns have multiple pawns (for the "Multi-Pawn Columns" rule)
                const multiPawnCols = [];
                if (isPawn) {
                    for (let c = 0; c <= 8; c++) {
                        const pawnsInThisCol = samePieces.filter(p => p.x === c);
                        if (pawnsInThisCol.length > 1) {
                            multiPawnCols.push(c);
                        }
                    }
                }

                // 3. Current column pieces
                const colPieces = samePieces.filter(p => p.x === startX);
                colPieces.sort((a, b) => a.y - b.y); // Sort by Y ascending (0 is top)

                let prefix = '';
                let location = '';
                const name = char;

                if (colPieces.length > 1) {
                    // Normalize order: Front-to-Back
                    let sortedInCol = [...colPieces];
                    if (isRed) {
                        sortedInCol.sort((a, b) => a.y - b.y); // For Red, smaller Y is "Front"
                    } else {
                        sortedInCol.sort((a, b) => b.y - a.y); // For Black, larger Y is "Front"
                    }
                    const pIdx = sortedInCol.findIndex(p => p.id === pieceId);

                    // Determine Prefix (Front/Middle/Back or digits)
                    if (colPieces.length === 2) {
                        prefix = (pIdx === 0) ? '+' : '-';
                    } else if (colPieces.length === 3) {
                        prefix = (pIdx === 0) ? '+' : (pIdx === 1 ? '=' : '-');
                    } else {
                        prefix = pIdx + 1;
                    }

                    // --- KEY FIX: Check for ambiguity across different columns ---
                    if (isPawn && multiPawnCols.length > 1 && prefix !== '=') {
                        // If more than one column has multiple pawns, use Column Number instead of "Pawn"
                        location = startCol;
                    } else {
                        location = name;
                    }
                } else {
                    prefix = name;
                    location = startCol;
                }

                // 4. Action and Value
                let action = '';
                let val = 0;
                if (startY === endY) {
                    action = '=';
                    val = endCol;
                } else {
                    const isAdvancing = isRed ? (startY > endY) : (startY < endY);
                    action = isAdvancing ? '+' : '-';
                    val = (['n', 'N', 'b', 'B', 'a', 'A', 'k', 'K'].includes(char)) ? endCol : Math.abs(startY - endY);
                }

                return prefix + location + action + val;
            }




一並連同function deriveCoordsFromMove也要修正:




            /**
             * Derives start and end coordinates from a FEN string and move notation.
             * Handles complex notations like "+C=5", "3p+1", and "+3=7".
             * * @param {string} fen - The FEN string before the move.
             * @param {string} move - The move notation (e.g., "C2=5", "+n+8", "3p+1").
             * @param {boolean} [isRed] - Optional flag indicating if it's Red's turn. 
             * If not provided, it parses it from the FEN string.
             * @returns {Object} An object containing { startX, startY, endX, endY }.
             */
            function deriveCoordsFromMove(fen, move, isRed) {
                // Determine player color from FEN if not explicitly provided
                if (typeof isRed === 'undefined') {
                    isRed = fen.includes(' w');
                }

                // 1. Parse the board from FEN to extract piece coordinates
                const boardPart = fen.split(' ')[0];
                const rows = boardPart.split('/');
                let myPieces = [];

                rows.forEach((row, y) => {
                    let x = 0;
                    for (let i = 0; i < row.length; i++) {
                        const char = row[i];
                        if (/[0-9]/.test(char)) {
                            // Skip empty squares
                            x += parseInt(char, 10);
                        } else {
                            // Check if the piece belongs to the current player
                            const pieceIsRed = (char >= 'A' && char <= 'Z');
                            if (pieceIsRed === isRed) {
                                myPieces.push({
                                    char,
                                    x,
                                    y
                                });
                            }
                            x++;
                        }
                    }
                });

                // 2. Dissect the 4-character move notation
                const char1 = move.charAt(0);
                const char2 = move.charAt(1);
                const action = move.charAt(2);
                const val = parseInt(move.slice(3), 10);

                let startX = -1;
                let startY = -1;
                let pieceType = '';

                /**
                 * Helper to select the correct piece based on prefix (+, -, =, 1, 2, 3...)
                 * Assumes the array is sorted from "Front" to "Back".
                 */
                const getPieceFromPrefix = (piecesInCol, prefix) => {
                    if (prefix === '+') return piecesInCol[0];
                    if (prefix === '-') return piecesInCol[piecesInCol.length - 1];
                    if (prefix === '=') return piecesInCol[1]; // Middle piece of 3
                    const num = parseInt(prefix, 10);
                    if (!isNaN(num) && num > 0) return piecesInCol[num - 1];
                    return piecesInCol[0]; // Fallback
                };

                // 3. Identify the moving piece and its starting coordinates
                if (/[a-zA-Z]/.test(char1) && /[0-9]/.test(char2)) {
                    // Case 1: Standard Notation (e.g., "C2=5", "P3+1", "n8+7")
                    pieceType = isRed ? char1.toUpperCase() : char1.toLowerCase();
                    const startCol = parseInt(char2, 10);
                    startX = isRed ? (9 - startCol) : (startCol - 1);

                    const candidate = myPieces.find(p => p.char === pieceType && p.x === startX);
                    if (candidate) {
                        startY = candidate.y;
                    }
                } else if (/[\+\-\=12345]/.test(char1) && /[a-zA-Z]/.test(char2)) {
                    // Case 2: Prefix + Piece Notation (e.g., "+C=5", "-n+8")
                    pieceType = isRed ? char2.toUpperCase() : char2.toLowerCase();

                    // Group pieces of this specific type by column
                    const typePieces = myPieces.filter(p => p.char === pieceType);
                    const colGroups = {};
                    typePieces.forEach(p => {
                        if (!colGroups[p.x]) colGroups[p.x] = [];
                        colGroups[p.x].push(p);
                    });

                    // Find the column that actually has multiple pieces of this type
                    let targetGroup = null;
                    for (let x in colGroups) {
                        if (colGroups[x].length > 1) {
                            targetGroup = colGroups[x];
                            break; // Usually only one column meets this criteria (except for pawns)
                        }
                    }

                    if (targetGroup) {
                        // Sort Front to Back: Red Front is smaller Y, Black Front is larger Y
                        targetGroup.sort((a, b) => isRed ? (a.y - b.y) : (b.y - a.y));
                        const candidate = getPieceFromPrefix(targetGroup, char1);
                        if (candidate) {
                            startX = candidate.x;
                            startY = candidate.y;
                        }
                    }
                } else if (/[\+\-\=12345]/.test(char1) && /[0-9]/.test(char2)) {
                    // Case 3: Prefix + Column Notation specifically for Pawns (e.g., "+3=4", "25+1")
                    pieceType = isRed ? 'P' : 'p';
                    const startCol = parseInt(char2, 10);
                    startX = isRed ? (9 - startCol) : (startCol - 1);

                    // Extract all pawns located on this specific column
                    const targetGroup = myPieces.filter(p => p.char === pieceType && p.x === startX);
                    if (targetGroup.length > 1) {
                        // Sort Front to Back
                        targetGroup.sort((a, b) => isRed ? (a.y - b.y) : (b.y - a.y));
                        const candidate = getPieceFromPrefix(targetGroup, char1);
                        if (candidate) {
                            startY = candidate.y;
                        }
                    }
                }

                // Safety check if notation parsing failed
                if (startX === -1 || startY === -1) {
                    console.error("Failed to derive start coordinates for move:", move);
                    return null;
                }

                // 4. Calculate target coordinates (endX, endY)
                let endX = -1;
                let endY = -1;

                // Some pieces use the `val` to represent the target column instead of step count
                const valIsEndCol = ['n', 'N', 'b', 'B', 'a', 'A', 'k', 'K'].includes(pieceType);

                if (action === '=') {
                    // Horizontal move: Y stays the same, X is directly derived from the target column
                    endX = isRed ? (9 - val) : (val - 1);
                    endY = startY;
                } else {
                    // Vertical or Diagonal move ('+' or '-')
                    // Direction multiplier: For Red, '+' means moving up (-Y). For Black, '+' means moving down (+Y).
                    const dir = isRed ? (action === '+' ? -1 : 1) : (action === '+' ? 1 : -1);

                    if (valIsEndCol) {
                        // For Knights, Elephants, Advisors, and King: The value indicates the target column
                        endX = isRed ? (9 - val) : (val - 1);
                        const dx = Math.abs(endX - startX);
                        let dy = 0;

                        const lowerType = pieceType.toLowerCase();
                        if (lowerType === 'n') {
                            dy = (dx === 1) ? 2 : 1; // Knight moves in 1x2 or 2x1 L-shape
                        } else if (lowerType === 'b') {
                            dy = 2; // Elephant moves 2x2 diagonally
                        } else if (lowerType === 'a' || lowerType === 'k') {
                            dy = 1; // Advisor moves 1x1 diagonally, King moves 1 step vertically
                        }

                        endY = startY + dir * dy;
                    } else {
                        // For linear pieces (Chariot, Cannon, Pawn): The value represents the number of steps
                        endX = startX;
                        const steps = val;
                        endY = startY + dir * steps;
                    }
                }

                return {
                    startX,
                    startY,
                    endX,
                    endY
                };
            }

給出修正後的完整代碼,並告知所改動的地方。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

代码: 全选

                const timestamp = now.toISOString().replace(/[-T:.Z]/g, '').slice(0, 14);
跟當前系統時間不符,修正為系統時間。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

改進:

const timestamp = now.toISOString().replace(/[-T:.Z]/g, '').slice(0, 14);
跟當前系統時間不符,修正為系統時間。

<span class="branch-delete-icon">刪除</span>
把「刪除」二字,替換成跟「btn-del-move」一樣的svg圖標。

把tool-open的圖標,換成另一個更像是「打開文件」的svg圖標。

只需給出要修改的地方,所有的代碼和注釋都要使用英文。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

AI確實給了很大的幫助,但是想要完全依靠AI還是不行的。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

代码: 全选

{"v":[{"m":"C2=5","v":[{"m":"c2=5","v":[{"m":"N2+3","v":[{"m":"n8+9","v":[{"m":"R1=2","v":[{"m":"r9=8","v":[{"m":"N8+7","v":[{"m":"n2+3","v":[{"m":"C8+4","v":[{"m":"r1+1","v":[{"m":"P7+1","v":[{"m":"r1=6","v":[{"m":"C5=6","v":[{"m":"p9+1","v":[{"m":"P3+1","c":"應直接跳馬","v":[{"m":"r6+3","v":[{"m":"N7+6","v":[{"m":"r6=2","v":[{"m":"P7+1","c":"炮被捉死,只好拱兵","v":[{"m":"r2-1","v":[{"m":"P7+1","v":[{"m":"r2+2","v":[{"m":"N6+4","v":[{"m":"n3-5","v":[{"m":"C6=5","v":[{"m":"r2=7","c":"黑方不夠穩健,應提砲看中卒。","v":[{"m":"C5+4","v":[{"m":"r7+2","v":[{"m":"N4+6","v":[{"m":"r7=4","v":[{"m":"R9+2","v":[{"m":"r4-3","v":[{"m":"R9=4","v":[{"m":"c8+1","v":[{"m":"R2+6","v":[{"m":"r8+3","v":[{"m":"A4+5","v":[{"m":"n9-8","v":[{"m":"C5=2","c":"錯誤,應先出帥","v":[{"m":"n5+7","v":[{"m":"N6+4","v":[{"m":"k5+5","v":[{"m":"P7+1","v":[{"m":"b7+9","v":[{"m":"C2=9","v":[{"m":"n8+6","v":[{"m":"C9=4","v":[{"m":"p7+1","v":[{"m":"C4+2","v":[{"m":"k5=6","v":[{"m":"P7=6","v":[{"m":"c5-2","c":"敗著!應直接兌車","v":[{"m":"N4-6","c":"妙手!回馬即擋住黑方吃兵,又能使對方不能兌車","v":[{"m":"k6=5","c":"錯過最後一次求和的機會,此時黑方應跳馬擋住","v":[{"m":"K5=4","v":[{"m":"c5+6","v":[{"m":"P6=5","c":"妙著連連,黑方招架不住","v":[{"m":"k5=4","v":[{"m":"N6+8","c":"紅勝"}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}],"fen":"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w"}
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

當分支被刪除時,如果刪的不是當前分支,則不必把後續分支都改成第一個分支。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 4574
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 172 次
被圈友点赞: 200 次
联系:

Re: 將製作ejcees(中國象棋打譜程式)

帖子 ejsoon »

代码: 全选

{"v":[{"m":"C2=5","v":[{"m":"c2=5","v":[{"m":"N2+3","v":[{"m":"n8+9","v":[{"m":"R1=2","v":[{"m":"r9=8","v":[{"m":"N8+7","v":[{"m":"n2+3","v":[{"m":"C8+4","v":[{"m":"p3+1","v":[{"m":"R2+5","v":[{"m":"r1=2","v":[{"m":"R9=8","v":[{"m":"c8=7","v":[{"m":"R2=7","v":[{"m":"r8+8","v":[{"m":"C5=6","v":[{"m":"r8=3","v":[{"m":"R8+2","v":[{"m":"r3+1","v":[{"m":"B3+5","v":[{"m":"r3-1","v":[{"m":"A4+5","v":[{"m":"p5+1","v":[{"m":"R7+1","v":[{"m":"p5+1","v":[{"m":"P5+1","v":[{"m":"r3-1","v":[{"m":"R8+2","v":[{"m":"r2+2","v":[{"m":"P5+1","v":[{"m":"p9+1","v":[{"m":"P5+1","v":[{"m":"c5+5","v":[{"m":"K5=4","v":[{"m":"a4+5","v":[{"m":"N3+5","v":[{"m":"r3+1","v":[{"m":"N5+4","v":[{"m":"c7-1","v":[{"m":"N4+6","v":[{"m":"n3-4","v":[{"m":"R8=4","v":[{"m":"r3-1","v":[{"m":"R4+4","v":[{"m":"r2=6","v":[{"m":"P5=4","v":[{"m":"r6=3","v":[{"m":"N6+7","v":[{"m":"-r-1","v":[{"m":"R7+2","v":[{"m":"r3=2","v":[{"m":"C8=5","v":[{"m":"b3+5","v":[{"m":"P4=3","c":"黑方認輸"}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}],"fen":"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w"}
黑方的車深入敵陣,雖然吃到了紅方一個馬和雙相,但其餘子力都被壓制,無法動彈。是得子失勢的經典案例。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 1 访客