用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。

1. 项目结构

/src/main/java/com/example/chinesechess/
    ├── MainAbilitySlice.java    // 主界面逻辑
    ├── ChessView.java          // 游戏视图和逻辑
    ├── ChessPiece.java         // 棋子类
    └── resources/
        ├── base/
        │   ├── layout/
        │   │   └── ability_main.xml  // 布局文件
        │   └── graphic/
        │       └── board_bg.xml      // 棋盘背景

2. 实现代码

ChessPiece.java (棋子类)

package com.example.chinesechess;

public class ChessPiece {
    public static final int RED = 0;
    public static final int BLACK = 1;
    
    private int type;   // 棋子类型
    private int color;  // 棋子颜色
    private int row;    // 行
    private int col;    // 列
    
    public ChessPiece(int type, int color, int row, int col) {
        this.type = type;
        this.color = color;
        this.row = row;
        this.col = col;
    }
    
    // 棋子类型常量
    public static final int GENERAL = 0;    // 将/帅
    public static final int ADVISOR = 1;    // 士
    public static final int ELEPHANT = 2;   // 象
    public static final int HORSE = 3;      // 马
    public static final int CHARIOT = 4;    // 车
    public static final int CANNON = 5;     // 炮
    public static final int SOLDIER = 6;    // 兵/卒
    
    // getter和setter方法
    public int getType() {
        return type;
    }
    
    public int getColor() {
        return color;
    }
    
    public int getRow() {
        return row;
    }
    
    public void setRow(int row) {
        this.row = row;
    }
    
    public int getCol() {
        return col;
    }
    
    public void setCol(int col) {
        this.col = col;
    }
    
    // 获取棋子名称
    public String getName() {
        String[] redNames = {"帅", "仕", "相", "马", "车", "炮", "兵"};
        String[] blackNames = {"将", "士", "象", "马", "车", "炮", "卒"};
        return color == RED ? redNames[type] : blackNames[type];
    }
}

ChessView.java (游戏视图和逻辑)

package com.example.chinesechess;

import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.agp.components.AttrSet;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;
import java.util.List;

public class ChessView extends Component implements Component.DrawTask {
    private static final int ROWS = 10;     // 棋盘行数
    private static final int COLS = 9;      // 棋盘列数
    
    private Paint linePaint;                // 棋盘线画笔
    private Paint redPaint;                 // 红方棋子画笔
    private Paint blackPaint;               // 黑方棋子画笔
    private Paint textPaint;                // 文字画笔
    private Paint selectedPaint;            // 选中状态画笔
    
    private List<ChessPiece> pieces;        // 棋子列表
    private ChessPiece selectedPiece;       // 当前选中的棋子
    private int currentPlayer = ChessPiece.RED; // 当前玩家
    
    public ChessView(Context context) {
        super(context);
        init();
    }
    
    public ChessView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init();
    }
    
    private void init() {
        linePaint = new Paint();
        linePaint.setColor(new Color(0xFF000000));
        linePaint.setStrokeWidth(2);
        
        redPaint = new Paint();
        redPaint.setColor(new Color(0xFFFF0000));
        redPaint.setStyle(Paint.Style.FILL_STYLE);
        
        blackPaint = new Paint();
        blackPaint.setColor(new Color(0xFF000000));
        blackPaint.setStyle(Paint.Style.FILL_STYLE);
        
        textPaint = new Paint();
        textPaint.setColor(new Color(0xFFFFFFFF));
        textPaint.setTextSize(40);
        textPaint.setTextAlign(Paint.Align.CENTER);
        
        selectedPaint = new Paint();
        selectedPaint.setColor(new Color(0x6600FF00));
        selectedPaint.setStyle(Paint.Style.FILL_STYLE);
        
        initPieces();
        addDrawTask(this);
        setTouchEventListener(this::onTouchEvent);
    }
    
    private void initPieces() {
        pieces = new ArrayList<>();
        
        // 初始化红方棋子
        pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.RED, 9, 0));
        pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.RED, 9, 1));
        pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.RED, 9, 2));
        pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.RED, 9, 3));
        pieces.add(new ChessPiece(ChessPiece.GENERAL, ChessPiece.RED, 9, 4));
        pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.RED, 9, 5));
        pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.RED, 9, 6));
        pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.RED, 9, 7));
        pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.RED, 9, 8));
        pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.RED, 7, 1));
        pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.RED, 7, 7));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 0));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 2));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 4));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 6));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 8));
        
        // 初始化黑方棋子
        pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.BLACK, 0, 0));
        pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.BLACK, 0, 1));
        pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.BLACK, 0, 2));
        pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.BLACK, 0, 3));
        pieces.add(new ChessPiece(ChessPiece.GENERAL, ChessPiece.BLACK, 0, 4));
        pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.BLACK, 0, 5));
        pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.BLACK, 0, 6));
        pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.BLACK, 0, 7));
        pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.BLACK, 0, 8));
        pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.BLACK, 2, 1));
        pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.BLACK, 2, 7));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 0));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 2));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 4));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 6));
        pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 8));
    }
    
    @Override
    public void onDraw(Component component, Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        float cellWidth = width / (float) COLS;
        float cellHeight = height / (float) ROWS;
        
        // 绘制棋盘
        drawBoard(canvas, width, height, cellWidth, cellHeight);
        
        // 绘制棋子
        drawPieces(canvas, cellWidth, cellHeight);
    }
    
    private void drawBoard(Canvas canvas, int width, int height, float cellWidth, float cellHeight) {
        // 绘制横线
        for (int i = 0; i < ROWS; i++) {
            float y = i * cellHeight;
            canvas.drawLine(0, y, width, y, linePaint);
        }
        
        // 绘制竖线
        for (int j = 0; j < COLS; j++) {
            float x = j * cellWidth;
            canvas.drawLine(x, 0, x, height, linePaint);
        }
        
        // 绘制楚河汉界
        float centerY = (ROWS / 2 - 0.5f) * cellHeight;
        canvas.drawText("楚河", width * 0.3f, centerY - 20, textPaint);
        canvas.drawText("汉界", width * 0.7f, centerY - 20, textPaint);
        
        // 绘制九宫格
        drawNinePalaces(canvas, cellWidth, cellHeight, 0); // 上方九宫格
        drawNinePalaces(canvas, cellWidth, cellHeight, 7); // 下方九宫格
    }
    
    private void drawNinePalaces(Canvas canvas, float cellWidth, float cellHeight, int startRow) {
        float left = 3 * cellWidth;
        float top = startRow * cellHeight;
        float right = 5 * cellWidth;
        float bottom = (startRow + 2) * cellHeight;
        
        // 绘制斜线
        canvas.drawLine(left, top, right, bottom, linePaint);
        canvas.drawLine(right, top, left, bottom, linePaint);
    }
    
    private void drawPieces(Canvas canvas, float cellWidth, float cellHeight) {
        for (ChessPiece piece : pieces) {
            float centerX = (piece.getCol() + 0.5f) * cellWidth;
            float centerY = (piece.getRow() + 0.5f) * cellHeight;
            float radius = Math.min(cellWidth, cellHeight) * 0.4f;
            
            // 绘制棋子背景
            Paint bgPaint = piece.getColor() == ChessPiece.RED ? redPaint : blackPaint;
            canvas.drawCircle(centerX, centerY, radius, bgPaint);
            
            // 绘制棋子文字
            textPaint.setColor(piece.getColor() == ChessPiece.RED ? Color.WHITE : Color.WHITE);
            canvas.drawText(piece.getName(), centerX, centerY + 15, textPaint);
            
            // 绘制选中状态
            if (piece == selectedPiece) {
                canvas.drawCircle(centerX, centerY, radius + 5, selectedPaint);
            }
        }
    }
    
    private boolean onTouchEvent(Component component, TouchEvent event) {
        if (event.getAction() == TouchEvent.PRIMARY_POINT_DOWN) {
            int width = getWidth();
            int height = getHeight();
            float cellWidth = width / (float) COLS;
            float cellHeight = height / (float) ROWS;
            
            int col = (int) (event.getPointerPosition(0).getX() / cellWidth);
            int row = (int) (event.getPointerPosition(0).getY() / cellHeight);
            
            if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
                handleClick(row, col);
            }
        }
        return true;
    }
    
    private void handleClick(int row, int col) {
        ChessPiece clickedPiece = getPieceAt(row, col);
        
        if (selectedPiece == null) {
            // 没有选中棋子时,尝试选中一个棋子
            if (clickedPiece != null && clickedPiece.getColor() == currentPlayer) {
                selectedPiece = clickedPiece;
                invalidate();
            }
        } else {
            // 已经选中了一个棋子
            if (clickedPiece != null && clickedPiece.getColor() == currentPlayer) {
                // 点击的是己方棋子,切换选中
                selectedPiece = clickedPiece;
                invalidate();
            } else {
                // 尝试移动棋子
                if (isValidMove(selectedPiece, row, col)) {
                    // 如果目标位置有对方棋子,则吃掉
                    if (clickedPiece != null) {
                        pieces.remove(clickedPiece);
                        // 检查是否将/帅被吃
                        if (clickedPiece.getType() == ChessPiece.GENERAL) {
                            gameOver(currentPlayer);
                            return;
                        }
                    }
                    
                    // 移动棋子
                    selectedPiece.setRow(row);
                    selectedPiece.setCol(col);
                    
                    // 切换玩家
                    currentPlayer = (currentPlayer == ChessPiece.RED) ? ChessPiece.BLACK : ChessPiece.RED;
                    selectedPiece = null;
                    invalidate();
                }
            }
        }
    }
    
    private ChessPiece getPieceAt(int row, int col) {
        for (ChessPiece piece : pieces) {
            if (piece.getRow() == row && piece.getCol() == col) {
                return piece;
            }
        }
        return null;
    }
    
    private boolean isValidMove(ChessPiece piece, int toRow, int toCol) {
        int fromRow = piece.getRow();
        int fromCol = piece.getCol();
        
        // 目标位置不能是己方棋子
        ChessPiece targetPiece = getPieceAt(toRow, toCol);
        if (targetPiece != null && targetPiece.getColor() == piece.getColor()) {
            return false;
        }
        
        // 根据棋子类型判断移动是否合法
        switch (piece.getType()) {
            case ChessPiece.GENERAL: // 将/帅
                return isValidGeneralMove(piece, fromRow, fromCol, toRow, toCol);
            case ChessPiece.ADVISOR: // 士
                return isValidAdvisorMove(piece, fromRow, fromCol, toRow, toCol);
            case ChessPiece.ELEPHANT: // 象
                return isValidElephantMove(piece, fromRow, fromCol, toRow, toCol);
            case ChessPiece.HORSE: // 马
                return isValidHorseMove(fromRow, fromCol, toRow, toCol);
            case ChessPiece.CHARIOT: // 车
                return isValidChariotMove(fromRow, fromCol, toRow, toCol);
            case ChessPiece.CANNON: // 炮
                return isValidCannonMove(fromRow, fromCol, toRow, toCol);
            case ChessPiece.SOLDIER: // 兵/卒
                return isValidSoldierMove(piece, fromRow, fromCol, toRow, toCol);
            default:
                return false;
        }
    }
    
    private boolean isValidGeneralMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {
        // 将/帅只能在九宫格内移动
        if (piece.getColor() == ChessPiece.RED) {
            if (toRow < 7 || toRow > 9 || toCol < 3 || toCol > 5) {
                return false;
            }
        } else {
            if (toRow < 0 || toRow > 2 || toCol < 3 || toCol > 5) {
                return false;
            }
        }
        
        // 将/帅每次只能走一格直线
        int rowDiff = Math.abs(toRow - fromRow);
        int colDiff = Math.abs(toCol - fromCol);
        
        if ((rowDiff == 1 && colDiff == 0) || (rowDiff == 0 && colDiff == 1)) {
            return true;
        }
        
        // 将帅对面特殊情况
        if (fromCol == toCol && colDiff == 0) {
            ChessPiece target = getPieceAt(toRow, toCol);
            if (target != null && target.getType() == ChessPiece.GENERAL && target.getColor() != piece.getColor()) {
                // 检查中间是否有其他棋子
                int minRow = Math.min(fromRow, toRow);
                int maxRow = Math.max(fromRow, toRow);
                for (int r = minRow + 1; r < maxRow; r++) {
                    if (getPieceAt(r, fromCol) != null) {
                        return false;
                    }
                }
                return true;
            }
        }
        
        return false;
    }
    
    private boolean isValidAdvisorMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {
        // 士只能在九宫格内移动
        if (piece.getColor() == ChessPiece.RED) {
            if (toRow < 7 || toRow > 9 || toCol < 3 || toCol > 5) {
                return false;
            }
        } else {
            if (toRow < 0 || toRow > 2 || toCol < 3 || toCol > 5) {
                return false;
            }
        }
        
        // 士每次只能走一格斜线
        int rowDiff = Math.abs(toRow - fromRow);
        int colDiff = Math.abs(toCol - fromCol);
        
        return rowDiff == 1 && colDiff == 1;
    }
    
    private boolean isValidElephantMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {
        // 象不能过河
        if (piece.getColor() == ChessPiece.RED && toRow < 5) {
            return false;
        }
        if (piece.getColor() == ChessPiece.BLACK && toRow > 4) {
            return false;
        }
        
        // 象走田字
        int rowDiff = Math.abs(toRow - fromRow);
        int colDiff = Math.abs(toCol - fromCol);
        
        if (rowDiff == 2 && colDiff == 2) {
            // 检查象眼是否被堵
            int eyeRow = (fromRow + toRow) / 2;
            int eyeCol = (fromCol + toCol) / 2;
            return getPieceAt(eyeRow, eyeCol) == null;
        }
        
        return false;
    }
    
    private boolean isValidHorseMove(int fromRow, int fromCol, int toRow, int toCol) {
        int rowDiff = Math.abs(toRow - fromRow);
        int colDiff = Math.abs(toCol - fromCol);
        
        // 马走日
        if ((rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2)) {
            // 检查马腿是否被堵
            if (rowDiff == 2) {
                int middleRow = (fromRow + toRow) / 2;
                return getPieceAt(middleRow, fromCol) == null;
            } else {
                int middleCol = (fromCol + toCol) / 2;
                return getPieceAt(fromRow, middleCol) == null;
            }
        }
        
        return false;
    }
    
    private boolean isValidChariotMove(int fromRow, int fromCol, int toRow, int toCol) {
        // 车走直线
        if (fromRow != toRow && fromCol != toCol) {
            return false;
        }
        
        // 检查路径上是否有其他棋子
        if (fromRow == toRow) {
            int minCol = Math.min(fromCol, toCol);
            int maxCol = Math.max(fromCol, toCol);
            for (int c = minCol + 1; c < maxCol; c++) {
                if (getPieceAt(fromRow, c) != null) {
                    return false;
                }
            }
        } else {
            int minRow = Math.min(fromRow, toRow);
            int maxRow = Math.max(fromRow, toRow);
            for (int r = minRow + 1; r < maxRow; r++) {
                if (getPieceAt(r, fromCol) != null) {
                    return false;
                }
            }
        }
        
        return true;
    }
    
    private boolean isValidCannonMove(int fromRow, int fromCol, int toRow, int toCol) {
        // 炮走直线
        if (fromRow != toRow && fromCol != toCol) {
            return false;
        }
        
        ChessPiece targetPiece = getPieceAt(toRow, toCol);
        int pieceCount = 0;
        
        // 计算路径上的棋子数量
        if (fromRow == toRow) {
            int minCol = Math.min(fromCol, toCol);
            int maxCol = Math.max(fromCol, toCol);
            for (int c = minCol + 1; c < maxCol; c++) {
                if (getPieceAt(fromRow, c) != null) {
                    pieceCount++;
                }
            }
        } else {
            int minRow = Math.min(fromRow, toRow);
            int maxRow = Math.max(fromRow, toRow);
            for (int r = minRow + 1; r < maxRow; r++) {
                if (getPieceAt(r, fromCol) != null) {
                    pieceCount++;
                }
            }
        }
        
        // 炮移动时不能有棋子阻挡
        if (targetPiece == null) {
            return pieceCount == 0;
        }
        // 炮吃子时必须有一个棋子作为炮架
        else {
            return pieceCount == 1;
        }
    }
    
    private boolean isValidSoldierMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {
        int rowDiff = toRow - fromRow;
        int colDiff = Math.abs(toCol - fromCol);
        
        if (piece.getColor() == ChessPiece.RED) {
            // 红方兵向上走
            if (rowDiff != -1) {
                return false;
            }
        } else {
            // 黑方卒向下走
            if (rowDiff != 1) {
                return false;
            }
        }
        
        // 未过河只能向前
        if ((piece.getColor() == ChessPiece.RED && fromRow > 4) || 
            (piece.getColor() == ChessPiece.BLACK && fromRow < 5)) {
            return colDiff == 0;
        }
        // 过河后可以左右移动
        else {
            return colDiff == 0 || colDiff == 1;
        }
    }
    
    private void gameOver(int winner) {
        String message = (winner == ChessPiece.RED) ? "红方胜利!" : "黑方胜利!";
        if (getContext() instanceof MainAbilitySlice) {
            ((MainAbilitySlice) getContext()).showGameOverDialog(message);
        }
        
        // 重置游戏
        initPieces();
        currentPlayer = ChessPiece.RED;
        selectedPiece = null;
        invalidate();
    }
    
    public void resetGame() {
        initPieces();
        currentPlayer = ChessPiece.RED;
        selectedPiece = null;
        invalidate();
    }
}

MainAbilitySlice.java (主界面)

package com.example.chinesechess;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.components.Button;

public class MainAbilitySlice extends AbilitySlice {
    private ChessView chessView;
    private Text statusText;
    
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        
        DirectionalLayout layout = new DirectionalLayout(this);
        layout.setOrientation(DirectionalLayout.VERTICAL);
        
        // 状态文本
        statusText = new Text(this);
        statusText.setText("当前回合: 红方");
        statusText.setTextSize(50);
        statusText.setPadding(10, 10, 10, 10);
        
        // 象棋视图
        chessView = new ChessView(this);
        
        // 按钮布局
        DirectionalLayout buttonLayout = new DirectionalLayout(this);
        buttonLayout.setOrientation(DirectionalLayout.HORIZONTAL);
        buttonLayout.setPadding(10, 10, 10, 10);
        
        // 重新开始按钮
        Button resetButton = new Button(this);
        resetButton.setText("重新开始");
        resetButton.setClickedListener(component -> {
            chessView.resetGame();
            statusText.setText("当前回合: 红方");
        });
        
        // 悔棋按钮
        Button undoButton = new Button(this);
        undoButton.setText("悔棋");
        undoButton.setClickedListener(component -> {
            // 悔棋功能待实现
            new ToastDialog(this).setText("悔棋功能待实现").show();
        });
        
        buttonLayout.addComponent(resetButton);
        buttonLayout.addComponent(undoButton);
        
        layout.addComponent(statusText);
        layout.addComponent(chessView);
        layout.addComponent(buttonLayout);
        
        super.setUIContent(layout);
    }
    
    public void showGameOverDialog(String message) {
        new ToastDialog(this)
            .setText(message)
            .show();
        statusText.setText("游戏结束 - " + message);
    }
}

ability_main.xml (布局文件)

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="match_parent"
    ohos:orientation="vertical">
    
    <Text
        ohos:id="$+id:status_text"
        ohos:width="match_parent"
        ohos:height="50vp"
        ohos:text="当前回合: 红方"
        ohos:text_size="20fp"
        ohos:padding="10vp"/>
        
    <com.example.chinesechess.ChessView
        ohos:id="$+id:chess_view"
        ohos:width="match_parent"
        ohos:height="0vp"
        ohos:weight="1"/>
        
    <DirectionalLayout
        ohos:id="$+id:button_layout"
        ohos:width="match_parent"
        ohos:height="wrap_content"
        ohos:orientation="horizontal"
        ohos:padding="10vp">
        
        <Button
            ohos:id="$+id:reset_button"
            ohos:width="0vp"
            ohos:height="50vp"
            ohos:weight="1"
            ohos:text="重新开始"
            ohos:margin="5vp"/>
            
        <Button
            ohos:id="$+id:undo_button"
            ohos:width="0vp"
            ohos:height="50vp"
            ohos:weight="1"
            ohos:text="悔棋"
            ohos:margin="5vp"/>
    </DirectionalLayout>
</DirectionalLayout>

3. 功能说明

  1. ​游戏规则​​:标准中国象棋规则
  2. ​棋子类型​​:
    • 将/帅、士、象、马、车、炮、兵/卒
  3. ​界面元素​​:
    • 棋盘:9×10网格,包含楚河汉界和九宫格
    • 棋子:红黑两色,带有汉字标识
    • 状态显示:当前回合信息
    • 操作按钮:重新开始、悔棋(待实现)
  4. ​交互​​:
    • 点击选中棋子
    • 再次点击目标位置移动棋子
    • 自动判断移动是否合法
    • 自动判断胜负
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值