Flutter 框架跨平台鸿蒙开发 - 鸿蒙版本中国象棋应用
运行效果图中国象棋是一款历史悠久的传统棋类游戏,蕴含着深厚的中华文化底蕴。本应用采用经典木纹棋盘设计,红黑双色棋子,完美还原真实对弈体验。双方轮流走棋,以将死对方将帅为目标。9×10的标准棋盘,楚河汉界分隔两军。七种棋子各具特色:帅将坐镇九宫,仕士护卫左右,相象田字巡边,车炮纵横驰骋,马踏八方,兵卒勇往直前。悔棋功能让玩家可以纠正失误,规则说明帮助新手快速入门。中国象棋应用通过经典的玩法设计和传统
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




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 整体架构图
2.2 类图设计
2.3 数据流程图
2.4 走棋流程
三、核心模块设计
3.1 数据模型设计
3.1.1 棋子类型枚举 (PieceType)
enum PieceType {
king, // 帅/将
advisor, // 仕/士
elephant, // 相/象
horse, // 马
rook, // 车
cannon, // 炮
pawn, // 兵/卒
}
3.1.2 棋子颜色枚举 (PieceColor)
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 棋盘布局
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 后续版本规划
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 开发注意事项
-
棋盘坐标:注意行列与屏幕坐标的映射
-
规则实现:每种棋子的走法规则要完整
-
边界检查:数组访问前检查边界
-
状态同步:走棋后及时更新游戏状态
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实现棋子显示和交互,选中高亮和有效目标标记帮助玩家快速识别可走位置。悔棋功能让玩家可以纠正失误,提升游戏体验。
更多推荐


所有评论(0)