Flutter 框架跨平台鸿蒙开发 - 鸿蒙版本五子棋游戏应用
文章摘要: 开源鸿蒙五子棋项目采用Flutter框架开发,支持跨平台运行。游戏基于15×15标准棋盘,实现双人对弈、胜负判定、悔棋等核心功能。技术栈包括Dart语言、Material Design 3规范,架构分为表现层、游戏逻辑层和数据层,使用状态管理和自定义绘制实现棋盘交互。项目包含完整的游戏流程控制、数据模型(棋子类型、游戏状态、落子记录)和胜负判定算法,提供规则说明、历史记录等功能,适合作
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图



1.1 应用简介
五子棋是一款经典的两人对弈策略游戏,规则简单但变化无穷。游戏采用传统木纹棋盘设计,黑白双色棋子,营造出真实的对弈氛围。双方轮流落子,先将五颗棋子连成一线者获胜。
15×15的标准棋盘提供了充足的博弈空间,横、竖、斜四个方向均可连线获胜。悔棋功能让玩家可以纠正失误,历史记录功能保存精彩对局。无论是休闲娱乐还是竞技对弈,五子棋都能带来无穷乐趣。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 棋盘显示 | 15×15标准棋盘 | CustomPaint绘制 |
| 落子操作 | 点击交叉点落子 | GestureDetector |
| 胜负判定 | 五子连线检测 | 四方向遍历算法 |
| 悔棋功能 | 撤销上一步棋 | 历史栈管理 |
| 当前玩家 | 显示轮到谁下棋 | 状态切换 |
| 历史记录 | 保存对局结果 | GameResult模型 |
| 游戏规则 | 规则说明弹窗 | AlertDialog |
1.3 游戏规则
| 规则项 | 说明 |
|---|---|
| 棋盘大小 | 15×15路标准棋盘 |
| 棋子颜色 | 黑方先行,白方后行 |
| 落子位置 | 棋盘交叉点 |
| 获胜条件 | 五子连成一线 |
| 连线方向 | 横、竖、斜均可 |
| 平局条件 | 棋盘下满仍未分胜负 |
1.4 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 目标平台 | 鸿蒙OS | API 21+ |
1.5 项目结构
lib/
└── main_gomoku.dart
├── GomokuApp # 应用入口
├── StoneType # 棋子类型枚举
├── GameState # 游戏状态枚举
├── Move # 落子记录模型
├── GameResult # 对局结果模型
├── HomePage # 主页面
│ ├── _buildStatusPanel() # 状态面板
│ ├── _buildBoard() # 棋盘区域
│ └── _buildControlPanel() # 控制面板
└── BoardPainter # 棋盘绘制器
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 数据流程图
2.4 游戏流程
三、核心模块设计
3.1 数据模型设计
3.1.1 棋子类型枚举 (StoneType)
enum StoneType {
black, // 黑子
white, // 白子
}
3.1.2 游戏状态枚举 (GameState)
3.1.3 落子记录模型 (Move)
class Move {
final int row; // 行坐标
final int col; // 列坐标
final StoneType stone; // 棋子颜色
final DateTime time; // 落子时间
}
3.1.4 对局结果模型 (GameResult)
class GameResult {
final StoneType winner; // 获胜方
final int moves; // 总步数
final Duration duration; // 对局时长
final DateTime date; // 对局日期
}
3.2 胜负判定算法
3.2.1 四方向检测
3.2.2 连线计数算法
int _countInDirection(int row, int col, int dRow, int dCol, StoneType stone) {
int count = 0;
int r = row + dRow;
int c = col + dCol;
while (r >= 0 && r < _boardSize && c >= 0 && c < _boardSize) {
if (_board[r][c] == stone) {
count++;
r += dRow;
c += dCol;
} else {
break;
}
}
return count;
}
3.2.3 方向向量
| 方向 | dRow | dCol | 说明 |
|---|---|---|---|
| 水平 | 0 | 1 | 从左到右 |
| 垂直 | 1 | 0 | 从上到下 |
| 主对角线 | 1 | 1 | 左上到右下 |
| 副对角线 | 1 | -1 | 右上到左下 |
3.3 页面结构设计
3.3.1 状态面板
3.3.2 棋盘区域
3.3.3 控制面板
3.4 状态管理
3.4.1 核心状态变量
class _HomePageState extends State<HomePage> {
static const int _boardSize = 15; // 棋盘大小
late List<List<StoneType?>> _board; // 棋盘数据
StoneType _currentPlayer = StoneType.black; // 当前玩家
GameState _gameState = GameState.playing; // 游戏状态
final List<Move> _moveHistory = []; // 落子历史
final List<GameResult> _gameHistory = []; // 对局历史
int? _lastMoveRow; // 最后落子行
int? _lastMoveCol; // 最后落子列
}
3.4.2 玩家切换
_currentPlayer = _currentPlayer == StoneType.black
? StoneType.white
: StoneType.black;
四、UI设计规范
4.1 配色方案
游戏采用传统木纹棋盘风格:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | Amber.shade800 | AppBar、按钮 |
| 棋盘背景 | #F5DEB3 | 小麦色背景 |
| 棋盘线 | Brown.shade700 | 棋盘网格线 |
| 星位点 | Brown.shade900 | 天元和星位 |
| 黑子 | #000000 | 黑方棋子 |
| 白子 | #FFFFFF | 白方棋子 |
| 最后落子标记 | 对比色 | 标识最后一步 |
4.2 棋盘设计
4.2.1 星位布局
┌───┬───┬───┬───┬───┬───┬───┐
│ │ │ │ │ │ │ │
├───┼───┼───┼───┼───┼───┼───┤
│ │ │ │ │ │ │ │
├───┼───┼───┼───┼───┼───┼───┤
│ │ │ ● │ │ │ ● │ │
├───┼───┼───┼───┼───┼───┼───┤
│ │ │ │ │ │ │ │
├───┼───┼───┼───●───┼───┼───┤ ● = 星位
│ │ │ ● │ │ │ ● │ │ 共9个星位点
├───┼───┼───┼───┼───┼───┼───┤
│ │ │ │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┘
4.2.2 星位坐标
| 位置 | 行 | 列 |
|---|---|---|
| 左上 | 3 | 3 |
| 中上 | 3 | 7 |
| 右上 | 3 | 11 |
| 左中 | 7 | 3 |
| 天元 | 7 | 7 |
| 右中 | 7 | 11 |
| 左下 | 11 | 3 |
| 中下 | 11 | 7 |
| 右下 | 11 | 11 |
4.3 组件规范
4.3.1 状态面板
┌─────────────────────────────────────────────────┐
│ ⚫ 黑方 🎲 对弈中 ⚪ 白方 │
│ 15步 第16手 15步 │
└─────────────────────────────────────────────────┘
4.3.2 棋子样式
┌─────────────┐ ┌─────────────┐
│ │ │ │
│ ⚫ │ │ ⚪ │
│ (黑子) │ │ (白子) │
│ │ │ 阴影效果 │
└─────────────┘ └─────────────┘
4.3.3 控制面板
┌─────────────────────────────────────────────────┐
│ ↩ 悔棋 🔄 重开 📖 规则 │
└─────────────────────────────────────────────────┘
4.4 交互设计
4.4.1 点击操作
| 操作 | 手势 | 效果 |
|---|---|---|
| 落子 | 单击空位 | 放置棋子 |
| 悔棋 | 点击按钮 | 撤销上一步 |
| 重开 | 点击按钮 | 重新开始 |
| 规则 | 点击按钮 | 显示规则 |
4.4.2 视觉反馈
五、核心功能实现
5.1 落子处理
void _placeStone(int row, int col) {
if (_gameState != GameState.playing) return;
if (_board[row][col] != null) return;
setState(() {
_board[row][col] = _currentPlayer;
_moveHistory.add(Move(
row: row,
col: col,
stone: _currentPlayer,
time: DateTime.now(),
));
_lastMoveRow = row;
_lastMoveCol = col;
if (_checkWin(row, col)) {
_gameState = _currentPlayer == StoneType.black
? GameState.blackWin
: GameState.whiteWin;
_saveResult();
} else if (_checkDraw()) {
_gameState = GameState.draw;
_saveResult();
} else {
_currentPlayer = _currentPlayer == StoneType.black
? StoneType.white
: StoneType.black;
}
});
}
5.2 胜负判定
bool _checkWin(int row, int col) {
final stone = _board[row][col];
if (stone == null) return false;
// 四个方向:水平、垂直、两条对角线
final directions = [
[0, 1], // 水平
[1, 0], // 垂直
[1, 1], // 主对角线
[1, -1], // 副对角线
];
for (var dir in directions) {
int count = 1;
// 正方向计数
count += _countInDirection(row, col, dir[0], dir[1], stone);
// 反方向计数
count += _countInDirection(row, col, -dir[0], -dir[1], stone);
if (count >= 5) return true;
}
return false;
}
5.3 悔棋功能
void _undoMove() {
if (_moveHistory.isEmpty) return;
if (_gameState != GameState.playing) return;
setState(() {
final lastMove = _moveHistory.removeLast();
_board[lastMove.row][lastMove.col] = null;
_currentPlayer = lastMove.stone;
// 更新最后落子标记
if (_moveHistory.isNotEmpty) {
final prevMove = _moveHistory.last;
_lastMoveRow = prevMove.row;
_lastMoveCol = prevMove.col;
} else {
_lastMoveRow = null;
_lastMoveCol = null;
}
});
}
5.4 棋盘绘制
class BoardPainter extends CustomPainter {
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.brown.shade700
..strokeWidth = 1
..style = PaintingStyle.stroke;
final cellSize = size.width / 15;
final offset = cellSize / 2;
// 绘制网格线
for (int i = 0; i < 15; i++) {
canvas.drawLine(
Offset(offset, offset + i * cellSize),
Offset(size.width - offset, offset + i * cellSize),
paint,
);
canvas.drawLine(
Offset(offset + i * cellSize, offset),
Offset(offset + i * cellSize, size.height - offset),
paint,
);
}
// 绘制星位点
final starPaint = Paint()
..color = Colors.brown.shade900
..style = PaintingStyle.fill;
final starPoints = [
[3, 3], [3, 7], [3, 11],
[7, 3], [7, 7], [7, 11],
[11, 3], [11, 7], [11, 11],
];
for (var point in starPoints) {
canvas.drawCircle(
Offset(offset + point[0] * cellSize, offset + point[1] * cellSize),
4,
starPaint,
);
}
}
}
六、五子棋策略知识
6.1 基础棋形
6.1.1 活四
6.1.2 冲四
6.1.3 活三
6.2 常见棋形对比
| 棋形 | 形状 | 威胁等级 | 应对策略 |
|---|---|---|---|
| 连五 | 五子连线 | 最高 | 游戏结束 |
| 活四 | 四子两端开放 | 极高 | 必须防守 |
| 冲四 | 四子一端被堵 | 高 | 可防守 |
| 活三 | 三子两端开放 | 中高 | 需防守 |
| 眠三 | 三子一端被堵 | 中 | 适度关注 |
6.3 开局策略
6.3.1 天元开局
6.3.2 开局原则
| 原则 | 说明 |
|---|---|
| 占据中心 | 天元附近控制力强 |
| 均衡发展 | 不要过于集中 |
| 攻守兼备 | 既进攻又防守 |
| 创造棋形 | 形成活三、活四 |
6.4 进阶技巧
6.4.1 双三
同时形成两个活三,对手无法同时防守。
○
○
○○○ ● ○○
○
○
6.4.2 四三
同时形成冲四和活三,必胜棋形。
● ○○○○
○
○
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 AI对战
class AIPlayer {
final Difficulty difficulty;
Move getBestMove(List<List<StoneType?>> board);
}
| 难度 | 算法 | 搜索深度 |
|---|---|---|
| 简单 | 随机+基础评估 | 1层 |
| 中等 | Minimax | 3层 |
| 困难 | Alpha-Beta剪枝 | 5层 |
7.2.2 复盘功能
| 功能 | 说明 |
|---|---|
| 步进回放 | 一步一步查看 |
| 关键点标记 | 标记重要棋形 |
| 分享功能 | 分享精彩对局 |
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_gomoku.dart
# 运行到Windows
flutter run -d windows -t lib/main_gomoku.dart
# 代码分析
flutter analyze lib/main_gomoku.dart
十、总结
五子棋游戏通过经典的玩法设计和传统木纹棋盘风格,为玩家提供了优雅的对弈体验。游戏采用15×15标准棋盘,黑白双色棋子,界面简洁大方;代码结构清晰,遵循Flutter最佳实践;胜负判定算法高效准确,支持四个方向的连线检测。
核心玩法涵盖落子对弈、胜负判定、悔棋功能和历史记录,满足玩家的基本需求。特别值得一提的是最后落子标记功能,帮助玩家快速定位最新棋局变化。悔棋功能让玩家可以纠正失误,提升游戏体验。
四方向连线检测算法是胜负判定的核心,通过遍历水平、垂直和两条对角线方向,准确判断五子连线。配合棋盘状态管理,实现了完整的游戏逻辑。历史记录功能保存精彩对局,见证玩家的进步。
更多推荐


所有评论(0)