news 2026/7/6 4:05:40

HarmonyOS 小游戏《对战五子棋》开发第5篇-五子棋GameConstants常量与类型定义最佳实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS 小游戏《对战五子棋》开发第5篇-五子棋GameConstants常量与类型定义最佳实践

好的常量设计让代码自文档化——从GameConstants看类型定义的艺术

代码如下:

/** * GameConstants.ets - 五子棋游戏常量与类型定义 *//** 棋盘尺寸 15x15 */exportconstBOARD_SIZE:number=15;/** 空位 */exportconstEMPTY:number=0;/** 黑棋 */exportconstBLACK:number=1;/** 白棋 */exportconstWHITE:number=2;/** AI难度等级 */exportenumDifficulty{EASY=1,NORMAL=2,HARD=3}/** 游戏结果 */exportenumGameResult{PLAYING=0,BLACK_WIN=1,WHITE_WIN=2,DRAW=3}/** 落子位置 */exportclassMove{row:number;col:number;constructor(row:number,col:number){this.row=row;this.col=col;}}/** 获取对手棋色 */exportfunctiongetOpponent(player:number):number{returnplayer===BLACK?WHITE:BLACK;}/** 颜色名称 */exportfunctionplayerName(player:number):string{returnplayer===BLACK?'黑方':'白方';}

为什么需要独立的常量文件

在游戏开发中,"魔法数字"是代码质量的头号杀手。对比两种写法:

// 差:到处是魔法数字if(board[7][7]===0){...}if(count>=5)returntrue;this.currentPlayer=player===1?2:1;// 好:语义清晰if(board[7][7]===EMPTY){...}if(count>=5)returntrue;// 5是五子棋的固有规则,可以接受this.currentPlayer=player===BLACK?WHITE:BLACK;

GameConstants完整解析

exportconstBOARD_SIZE:number=15;// 15x15标准棋盘exportconstEMPTY:number=0;// 空位exportconstBLACK:number=1;// 黑棋exportconstWHITE:number=2;// 白棋

为什么棋子用数字而不是字符串

  1. 性能:数字比较比字符串快
  2. 内存:number占用的内存远小于string
  3. 数组存储:棋盘是number[][],用数字最自然
  4. 序列化:数字序列化/反序列化更简单

枚举设计

exportenumDifficulty{EASY=1,NORMAL=2,HARD=3}exportenumGameResult{PLAYING=0,BLACK_WIN=1,WHITE_WIN=2,DRAW=3}

设计要点:

  • 枚举值从1开始(0留给"无"或默认状态)
  • GameResult.PLAYING = 0作为默认值
  • 枚举名用大写驼峰,语义明确

Move类

exportclassMove{row:number;col:number;constructor(row:number,col:number){this.row=row;this.col=col;}}

Move是五子棋中最基础的数据结构——表示棋盘上的一个位置。用class而非interface是因为Move经常需要new Move(row, col)创建实例。

辅助函数

exportfunctiongetOpponent(player:number):number{returnplayer===BLACK?WHITE:BLACK;}exportfunctionplayerName(player:number):string{returnplayer===BLACK?'黑方':'白方';}

这两个工具函数被多处复用:

  • getOpponent:引擎中切换玩家、AI中获取人类棋色
  • playerName:UI中显示当前玩家

常量设计的通用原则

1. 集中管理

所有游戏常量放在一个文件中,方便查找和修改:

// 改棋盘大小只需改一处exportconstBOARD_SIZE:number=15;// 改成19就是围棋棋盘

2. 命名清晰

  • BOARD_SIZE而非SIZEBS
  • EMPTY而非EMPTY_CELLNONE
  • BLACK/WHITE而非COLOR_BLACK/COLOR_WHITE

3. 语义分组

// 棋盘相关exportconstBOARD_SIZE=15;exportconstEMPTY=0;// 棋子相关exportconstBLACK=1;exportconstWHITE=2;// 游戏状态exportenumGameResult{...}// AI相关exportenumDifficulty{...}

AI评分常量

AIPlayer中定义了一套完整的评分常量:

constSCORE_FIVE:number=1000000;// 五连constSCORE_OPEN_FOUR:number=100000;// 活四constSCORE_FOUR:number=10000;// 冲四constSCORE_OPEN_THREE:number=8000;// 活三constSCORE_THREE:number=500;// 眠三constSCORE_OPEN_TWO:number=400;// 活二constSCORE_TWO:number=50;// 眠二constSCORE_ONE:number=10;// 单子

分值设计逻辑:

  • 五连 > 活四 > 冲四 > 活三 > 眠三 > 活二 > 眠二 > 单子
  • 相邻级别约10倍差距,确保高级棋型优先
  • 活四(100000)是冲四(10000)的10倍,因为活四必胜而冲四可防

总结

GameConstants虽然只有50行代码,但它奠定了整个项目的类型基础。好的常量设计能:

  1. 消除魔法数字,提高可读性
  2. 集中管理,方便修改
  3. 提供类型安全,减少bug
  4. 自文档化,降低理解成本

附:


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 4:05:10

如何提升工作中的影响力

回到阔别了十几年的故乡——上海让我倍感兴奋,这个城市的蓬勃生命力让我倍感激动。培育人才同样是一件令人激动的事,尤其是为华裔员工、女性员工提供职业指导和咨询。过去几年,这一直是我在美国总部工作的一部分。我经常会为他们的努力而感动…

作者头像 李华
网站建设 2026/7/6 4:04:40

Jstack定位生产环境线程阻塞问题解决

一、问题现象告警现象:有一个异步处理的任务日志没有往后继续打印了这个任务对应的队列存在消息积压系统日志无任何ERROR堆栈,服务既不崩溃也不恢复第一反应: 服务没挂但卡住了,极大概率是线程阻塞问题。二、初步诊断:…

作者头像 李华
网站建设 2026/7/6 4:04:32

从零搭建一个单节点 K8S 可观测实验室(一):从 Ubuntu 24.04 开始

最近准备把前段时间自己搭过的一套环境整理成系列文章:从零搭建一个单节点 K8S 可观测实验室。这个系列不是为了搭一个生产级 Kubernetes 集群,也不是为了追求复杂架构,而是想从一台普通的本地虚拟机开始,逐步搭出一个可以长期使用…

作者头像 李华
网站建设 2026/7/6 4:03:55

调试的艺术——从“打印大法”到“bug消失术”

引言 凌晨两点,你的代码编译通过了,运行却崩溃了。错误信息是一行看不懂的 Segmentation fault (core dumped)。你在第42行加了一行 cout << "here" << endl;,重新编译,运行——输出了一堆"here",然后在某个地方突然停了。你继续加打印,…

作者头像 李华
网站建设 2026/7/6 4:03:09

Java 日志框架清单

这份清单涵盖了Java生态中从核心门面&#xff08;API&#xff09;到具体实现&#xff08;Impl&#xff09;&#xff0c;再到高性能异步方案的全景图。为了方便快速决策&#xff0c;先按使用场景给出选型&#xff0c;下面是完整的分类清单。&#x1f680; 快速选型指南&#xff…

作者头像 李华