我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。
1. 问题描述
如果让你做个联机《五子棋》游戏,你会怎么存储棋盘上的棋子信息呢?
我的意思是,根据你存储的这些信息,就可以知道:
- 谁是黑棋?谁是白棋?
- 现在游戏结束了吗?若游戏结束,谁赢了?若没结束,现在该谁下棋了?
- 如果游戏支持悔棋,现在有人在请求悔棋吗?是谁在请求?
- 如果游戏支持认输,重新审视是否满足第2点。
- 当前场上棋子的分布。
请你自己先思考一下,再看下文的解决方案。
2. 解决方案
2.1 谁黑谁白
优点 | 缺点 | 适用范围 | |
---|---|---|---|
方案一:用1个变量标识你是哪个玩家;再用1个变量标识哪个玩家是黑棋。 | 有玩家号码标识,可扩展性好 | 游戏其它功能需要跟玩家编号有关联时可用该方案。 | |
方案二:用1个变量标识你是黑棋或白棋。 | 只需要1位(bit)即可 | 因为玩家没有固定的玩家号码,所以可扩展性较差 | 不做扩展功能,只做最简洁的联机五子棋时可用该方案。 |
两个方案都是可以的,只是需要看实际场景。如果你只想做个简单的五子棋,用方案二就够了。如果考虑扩展性,推荐方案一。
2.2 游戏结束了吗?谁赢了?该谁下棋了?
优点 | 缺点 | 适用范围 | |
---|---|---|---|
方案一:用1个变量标识游戏状态。黑赢、黑输、该玩家1下棋、该玩家2下棋等都是一种状态。 | 少了运算过程,快了几十毫秒。游戏状态的可扩展性好,可以新增状态(例如认输、悔棋等) | 游戏会有多种状态时可用该方案。 | |
方案二:只记录场上棋子的分布情况,通过计算是否有5连珠,判断谁输谁赢。 | 占用空间少 | 若要支持认输,只能回到方案一。 | 不做认输功能,只做最简洁的联机五子棋时可用该方案。 |
两个方案都是可以的,只是需要看实际场景。如果你只想做个简单的五子棋,用方案二就够了。如果考虑扩展性,推荐方案一。
2.3 悔棋
悔棋有2种形态:
- 请求悔棋后,无需对方确认,直接悔棋。
- 请求悔棋后,需要对方同意,才能悔棋成功。
第一种形态比较简单,悔棋后,直接更新游戏数据即可。
第二种形态,可以通过2.2的方案一来实现。游戏状态如下:
- 等黑下棋
- 等白下棋
- 黑胜利
- 白胜利
- 黑请求悔棋
- 白请求悔棋
2.4 认输
认输和悔棋不同,认输是单方面提出认输,游戏即可结束,宣布另一方的胜利。
可以通过2.2的方案一来实现,游戏状态同2.3即可实现认输功能。
2.5 状态机
下面,看看这些状态的转换关系:
图中没把「认输」动作画出来,因为「认输」比较简单,从其它四个状态分别拉2个线,指向「黑胜利」和「白胜利」,表示「白认输」和「黑认输」即可。
2.6 场上棋子分布
注:五子棋棋盘通常是15X15的布局,也有AI对战中,使用更大的棋盘,例如20X20。这里我们以15X15的棋盘来分析。
优点 | 缺点 | 适用范围 | |
---|---|---|---|
方案一:用一个列表存储已落的棋子,列表顺序表明棋子顺序,列表每一项的值代表棋子的位置,值为0-224(刚好225个值),奇数位置是黑棋,偶数位置是白棋。 | 针对棋子少的棋局,存储空间小于方案二;保存了位置信息,便于悔棋、复盘等。 | 每个棋子需要8bit存储,空间利用率约225/256=88%,并没有充分利用 | 大多数场景。 |
方案二:使用长度为225的列表,值为0或1或2,分别表示该位置没棋、黑棋、白棋。 | 针对任意棋子分布,占用空间是固定的。若用3进制,只需225bit,转换为2进制,只需要log_2(3^225)=357位 | 如果想记录顺序信息,需要额外空间。 | 你用这个棋盘画画的时候,棋子往往很多,且不需要保留顺序信息,可用该方案。 |
场上小于357/8=45枚棋子时,方案一占空间更小,否则方案二空间更小。
如果是联机《五子棋》游戏,推荐方案一,毕竟顺序信息还是很有用的。而存储空间大一点也是没关系的,影响可忽略不计。
另外补充一句,棋子位置信息存储时可以直接用0-224,但是转义给人类时,建议直接转换为15进制,这样它的十位就可以是行信息,个位就可以是列信息。
- 例如224=
ee
,表明第e(15)行第e(15)列; - 例如0=
00
,表明第0行第0列; - 例如10=
0a
,表明第0行,第a(10)列。
3. 写在最后
这些东西,你不去自己开发《五子棋》,可能不会去思考。但是当你做的时候,会发现,非常好玩儿,实现方案很多,你要选出最适合你的那一个。
其中,我做了「分享棋局」的功能,正是采用了十五进制,将棋子信息存在URL中,使之具有一点点可读性。参考文章:《我做的《联机五子棋》是如何追求极致用户体验的?(下)》
我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。