欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

image-20260404233314268

image-20260404233323215

image-20260404233346016

image-20260404233351276

1.1 应用简介

中国象棋是一款历史悠久的传统棋类游戏,蕴含着深厚的中华文化底蕴。本应用采用经典木纹棋盘设计,红黑双色棋子,完美还原真实对弈体验。双方轮流走棋,以将死对方将帅为目标。

9×10的标准棋盘,楚河汉界分隔两军。七种棋子各具特色:帅将坐镇九宫,仕士护卫左右,相象田字巡边,车炮纵横驰骋,马踏八方,兵卒勇往直前。悔棋功能让玩家可以纠正失误,规则说明帮助新手快速入门。

1.2 核心功能

功能模块 功能描述 实现方式
棋盘绘制 9×10棋盘+楚河汉界 CustomPaint
棋子显示 32枚棋子 Container+Text
走棋规则 七种棋子走法 规则验证函数
吃子判定 吃掉对方棋子 目标位置检测
胜负判定 将帅被吃 游戏结束检测
悔棋功能 撤销上一步 历史栈管理
规则说明 游戏规则弹窗 AlertDialog

1.3 棋子配置

棋子 红方名称 黑方名称 数量 走法
帅/将 1 九宫内直走一步
仕/士 2 九宫内斜走一步
相/象 2 田字走法,不能过河
2 日字走法,蹩马腿
2 直线走,不限步数
2 直线走,隔子吃
兵/卒 5 过河前只能前进

1.4 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
状态管理 setState -
目标平台 鸿蒙OS API 21+

1.5 项目结构

lib/
└── main_chinese_chess.dart
    ├── ChineseChessApp      # 应用入口
    ├── PieceType            # 棋子类型枚举
    ├── PieceColor           # 棋子颜色枚举
    ├── ChessPiece           # 棋子模型
    ├── Move                 # 走棋记录模型
    ├── HomePage             # 主页面
    │   ├── _buildStatusPanel()  # 状态面板
    │   ├── _buildBoard()        # 棋盘区域
    │   └── _buildControlPanel() # 控制面板
    └── ChessBoardPainter    # 棋盘绘制器

二、系统架构

2.1 整体架构图

Game Logic

Presentation Layer

Data Layer

Board
棋盘数据

Move
走棋记录

ChessPiece
棋子模型

状态面板

红方信息

游戏状态

黑方信息

棋盘区域

棋盘绘制

棋子显示

控制面板

悔棋/重开/规则

走棋处理
_selectCell

规则验证
_isValidMove

悔棋处理
_undoMove

胜负判定
_makeMove

2.2 类图设计

contains

manages

records

has

has

ChineseChessApp

+Widget build()

HomePage

-List<List<ChessPiece?>> _board

-PieceColor _currentPlayer

-int? _selectedRow

-int? _selectedCol

-List<Move> _moveHistory

-bool _gameOver

+Widget build()

-void _selectCell()

-bool _isValidMove()

-void _makeMove()

-void _undoMove()

ChessPiece

+PieceType type

+PieceColor color

+String name

Move

+int fromRow

+int fromCol

+int toRow

+int toCol

+ChessPiece? capturedPiece

«enumeration»

PieceType

king

advisor

elephant

horse

rook

cannon

pawn

«enumeration»

PieceColor

red

black

2.3 数据流程图

选择棋子

走棋

悔棋

游戏开始

初始化棋盘

放置棋子

玩家操作

高亮显示

规则验证

撤销上一步

是否合法

执行走棋

吃掉将帅?

游戏结束

切换玩家

2.4 走棋流程

棋盘数据 规则验证 游戏界面 玩家 棋盘数据 规则验证 游戏界面 玩家 alt [合法走法] [非法走法] 点击棋子 高亮选中 点击目标位置 验证走法 检查棋子类型 检查路径障碍 返回结果 更新位置 返回新状态 判断胜负 无效提示

三、核心模块设计

3.1 数据模型设计

3.1.1 棋子类型枚举 (PieceType)
enum PieceType {
  king,      // 帅/将
  advisor,   // 仕/士
  elephant,  // 相/象
  horse,     // 马
  rook,      // 车
  cannon,    // 炮
  pawn,      // 兵/卒
}
3.1.2 棋子颜色枚举 (PieceColor)
50% 50% 棋子颜色分布 红方(16子) 黑方(16子)
3.1.3 棋子模型 (ChessPiece)
class ChessPiece {
  final PieceType type;   // 棋子类型
  final PieceColor color; // 棋子颜色
  final String name;      // 显示名称
}
3.1.4 走棋记录模型 (Move)
class Move {
  final int fromRow;           // 起始行
  final int fromCol;           // 起始列
  final int toRow;             // 目标行
  final int toCol;             // 目标列
  final ChessPiece? capturedPiece; // 被吃的棋子
}

3.2 走棋规则实现

3.2.1 帅/将走法

检查移动距离

是否为一步?

非法

是否在九宫内?

合法

九宫范围

  • 红方:行7-9,列3-5
  • 黑方:行0-2,列3-5
3.2.2 仕/士走法

检查移动方向

是否斜走?

非法

是否一步?

是否在九宫内?

合法

3.2.3 相/象走法

检查移动距离

是否为田字?

非法

象眼是否被堵?

是否过河?

合法

象眼位置:起点和终点之间的格子

3.2.4 马走法

检查移动形状

是否为日字?

非法

马腿是否被蹩?

合法

马腿位置

  • 竖走两格:马腿在竖向第一格
  • 横走两格:马腿在横向第一格
3.2.5 车走法

检查移动方向

是否直线?

非法

路径是否有障碍?

合法

3.2.6 炮走法

空位

有子

不为一

恰好一

检查移动方向

是否直线?

非法

目标位置?

路径是否有障碍?

合法移动

中间隔几子?

合法吃子

3.2.7 兵/卒走法

检查是否过河

已过河?

是否前进?

非法

合法

前进或横走?

合法

过河线

  • 红方:行小于5
  • 黑方:行大于4

3.3 页面结构设计

3.3.1 棋盘布局

棋盘区域

CustomPaint

横线10条

竖线9条

九宫斜线

楚河汉界

GridView

90个格子

棋子显示

选中高亮

有效目标标记

3.3.2 棋盘绘制
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 車│ 馬│ 象│ 士│ 將│ 士│ 象│ 馬│ 車│
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │ 砲│   │   │   │   │   │ 砲│   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│ 卒│   │ 卒│   │ 卒│   │ 卒│   │ 卒│
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │
├───┴───┴───┴───┴───┴───┴───┴───┴───┤
│          楚 河      漢 界           │
├───┬───┬───┬───┬───┬───┬───┬───┬───┤
│   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│ 兵│   │ 兵│   │ 兵│   │ 兵│   │ 兵│
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │ 炮│   │   │   │   │   │ 炮│   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│ 車│ 馬│ 相│ 仕│ 帥│ 仕│ 相│ 馬│ 車│
└───┴───┴───┴───┴───┴───┴───┴───┴───┘

3.4 状态管理

3.4.1 核心状态变量
class _HomePageState extends State<HomePage> {
  static const int _rows = 10;              // 棋盘行数
  static const int _cols = 9;               // 棋盘列数
  late List<List<ChessPiece?>> _board;      // 棋盘数据
  PieceColor _currentPlayer = PieceColor.red; // 当前玩家
  int? _selectedRow;                        // 选中行
  int? _selectedCol;                        // 选中列
  final List<Move> _moveHistory = [];       // 走棋历史
  bool _gameOver = false;                   // 游戏是否结束
  String? _winner;                          // 获胜方
}
3.4.2 玩家切换
_currentPlayer = _currentPlayer == PieceColor.red
    ? PieceColor.black
    : PieceColor.red;

四、UI设计规范

4.1 配色方案

游戏采用传统木纹棋盘风格:

颜色类型 色值 用途
主色 Red.shade800 AppBar、按钮
棋盘背景 #F5DEB3 小麦色背景
棋盘线 Brown.shade800 棋盘网格线
红方棋子 Red.shade800 红方文字
黑方棋子 Black 黑方文字
棋子背景 #F5DEB3 棋子底色

4.2 棋子样式

4.2.1 棋子布局
┌─────────────────────────────────────┐
│              ╭─────╮               │
│              │ 帥  │               │
│              ╰─────╯               │
│           圆形棋子+边框             │
│        红方红字/黑方黑字            │
└─────────────────────────────────────┘
4.2.2 棋子名称对照
类型 红方 黑方
帅/将
仕/士
相/象
兵/卒

4.3 组件规范

4.3.1 状态面板
┌─────────────────────────────────────────────────┐
│  ⚫ 红方        🎲 红方走棋        ⚪ 黑方      │
│    16子          第1手            16子          │
└─────────────────────────────────────────────────┘
4.3.2 控制面板
┌─────────────────────────────────────────────────┐
│     ↩ 悔棋        🔄 重开        📖 规则       │
└─────────────────────────────────────────────────┘

4.4 交互设计

4.4.1 点击操作
操作 手势 效果
选择棋子 单击己方棋子 高亮选中
走棋 单击有效位置 移动棋子
取消选择 再次点击选中棋子 取消高亮
切换选择 点击其他己方棋子 切换选中
4.4.2 视觉反馈

选中棋子

蓝色边框高亮

显示有效目标

绿色半透明标记


五、核心功能实现

5.1 棋盘初始化

void _initBoard() {
  _board = List.generate(_rows, (_) => List.generate(_cols, (_) => null));
  _setupPieces();
  _currentPlayer = PieceColor.red;
  _selectedRow = null;
  _selectedCol = null;
  _moveHistory.clear();
  _gameOver = false;
  _winner = null;
}

5.2 走棋处理

void _selectCell(int row, int col) {
  if (_gameOver) return;

  final piece = _board[row][col];

  if (_selectedRow == null || _selectedCol == null) {
    // 选择棋子
    if (piece != null && piece.color == _currentPlayer) {
      setState(() {
        _selectedRow = row;
        _selectedCol = col;
      });
    }
  } else {
    if (row == _selectedRow && col == _selectedCol) {
      // 取消选择
      setState(() {
        _selectedRow = null;
        _selectedCol = null;
      });
    } else if (piece != null && piece.color == _currentPlayer) {
      // 切换选择
      setState(() {
        _selectedRow = row;
        _selectedCol = col;
      });
    } else if (_isValidMove(_selectedRow!, _selectedCol!, row, col)) {
      // 执行走棋
      _makeMove(_selectedRow!, _selectedCol!, row, col);
    }
  }
}

5.3 规则验证示例

// 马走法验证
bool _isValidHorseMove(int fromRow, int fromCol, int toRow, int toCol) {
  int rowDiff = (toRow - fromRow).abs();
  int colDiff = (toCol - fromCol).abs();

  // 检查是否为日字
  if (!((rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2))) {
    return false;
  }

  // 检查蹩马腿
  int legRow = fromRow;
  int legCol = fromCol;
  if (rowDiff == 2) {
    legRow = fromRow + (toRow > fromRow ? 1 : -1);
  } else {
    legCol = fromCol + (toCol > fromCol ? 1 : -1);
  }
  if (_board[legRow][legCol] != null) return false;

  return true;
}

5.4 悔棋功能

void _undoMove() {
  if (_moveHistory.isEmpty || _gameOver) return;

  final move = _moveHistory.removeLast();
  setState(() {
    // 恢复棋子位置
    _board[move.fromRow][move.fromCol] = _board[move.toRow][move.toCol];
    _board[move.toRow][move.toCol] = move.capturedPiece;
    // 切换回上一个玩家
    _currentPlayer = _currentPlayer == PieceColor.red 
        ? PieceColor.black 
        : PieceColor.red;
    _selectedRow = null;
    _selectedCol = null;
  });
}

5.5 棋盘绘制

class ChessBoardPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final cellWidth = size.width / 9;
    final cellHeight = size.height / 10;

    // 绘制横线
    for (int i = 0; i < 10; i++) {
      canvas.drawLine(
        Offset(offsetX, offsetY + i * cellHeight),
        Offset(size.width - offsetX, offsetY + i * cellHeight),
        linePaint,
      );
    }

    // 绘制竖线(注意楚河汉界处断开)
    for (int i = 0; i < 9; i++) {
      if (i == 0 || i == 8) {
        // 边线完整绘制
        canvas.drawLine(...);
      } else {
        // 中间线分两段绘制
        canvas.drawLine(...); // 上半部分
        canvas.drawLine(...); // 下半部分
      }
    }

    // 绘制九宫斜线
    // 绘制楚河汉界文字
  }
}

六、象棋知识拓展

6.1 基本杀法

6.1.1 铁门栓

车封锁中路

帅镇中路

形成绝杀

6.1.2 双车错

双车配合

交替将军

对方无法防守

6.1.3 马后炮
    炮
    │
    马 ── 将

马控制将的退路,炮在马后将军。

6.2 开局原则

原则 说明
出动大子 优先出车、马、炮
控制中路 占据战略要地
协调阵型 左右均衡发展
保护将帅 注意防守安全

6.3 残局技巧

6.3.1 单车必胜士象全

单车

破士或破象

形成单车胜士或象

逐步吃子获胜

6.3.2 马炮胜士象全
组合 难度 关键点
马炮双攻 中等 配合默契
炮镇中路 简单 控制中路
马踏边角 中等 灵活机动

七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 核心游戏逻辑 七种棋子规则 悔棋功能 AI对战 难度选择 音效系统 在线对战 复盘功能 棋谱保存 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 中国象棋开发计划

7.2 功能扩展建议

7.2.1 AI对战
class ChessAI {
  final int difficulty;
  
  Move getBestMove(List<List<ChessPiece?>> board);
}
难度 算法 搜索深度
入门 随机走法 1层
初级 简单评估 2层
中级 Alpha-Beta 3层
高级 深度搜索 4层+
7.2.2 复盘功能
功能 说明
步进回放 一步一步查看
关键标注 标注重要棋步
分享棋谱 导出PGN格式
7.2.3 在线对战
功能 说明
匹配系统 按段位匹配
排位赛 升降段位
好友对战 邀请好友

八、注意事项

8.1 开发注意事项

  1. 棋盘坐标:注意行列与屏幕坐标的映射

  2. 规则实现:每种棋子的走法规则要完整

  3. 边界检查:数组访问前检查边界

  4. 状态同步:走棋后及时更新游戏状态

8.2 游戏体验优化

🎮 游戏体验建议 🎮

  • 添加走棋音效
  • 显示有效走法提示
  • 支持棋盘缩放
  • 添加思考时间显示

8.3 常见问题

问题 原因 解决方案
走法无效 规则判断错误 检查规则函数
吃子异常 目标位置判断错误 检查颜色判断
悔棋错误 状态未正确恢复 检查历史记录
棋盘显示异常 绘制参数错误 检查CustomPaint

九、运行说明

9.1 环境要求

环境 版本要求
Flutter SDK >= 3.0.0
Dart SDK >= 2.17.0
鸿蒙OS API 21+

9.2 运行命令

# 查看可用设备
flutter devices

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_chinese_chess.dart

# 运行到Windows
flutter run -d windows -t lib/main_chinese_chess.dart

# 代码分析
flutter analyze lib/main_chinese_chess.dart

十、总结

中国象棋应用通过经典的玩法设计和传统木纹棋盘风格,为玩家提供了真实的对弈体验。游戏采用9×10标准棋盘,楚河汉界分隔两军,红黑双方各16枚棋子;代码结构清晰,遵循Flutter最佳实践;七种棋子走法规则完整,胜负判定准确。

核心玩法涵盖双人对弈、走棋规则验证、吃子判定、胜负判定和悔棋功能,满足象棋爱好者的基本需求。特别值得一提的是完整的走法规则实现,包括马的蹩腿、象的塞眼、炮的隔子吃等细节规则,确保游戏的专业性。

棋盘绘制采用CustomPaint,实现了横竖线、九宫斜线、楚河汉界等经典元素。配合GridView实现棋子显示和交互,选中高亮和有效目标标记帮助玩家快速识别可走位置。悔棋功能让玩家可以纠正失误,提升游戏体验。

**楚河汉界,纵横捭阖,智谋天下!
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐