[教你做小游戏]|[教你做小游戏] 《五子棋》怎么存棋局信息()

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。
1. 问题描述 如果让你做个联机《五子棋》游戏,你会怎么存储棋盘上的棋子信息呢?
我的意思是,根据你存储的这些信息,就可以知道:
  1. 谁是黑棋?谁是白棋?
  2. 现在游戏结束了吗?若游戏结束,谁赢了?若没结束,现在该谁下棋了?
  3. 如果游戏支持悔棋,现在有人在请求悔棋吗?是谁在请求?
  4. 如果游戏支持认输,重新审视是否满足第2点。
  5. 当前场上棋子的分布。
请你自己先思考一下,再看下文的解决方案。
2. 解决方案 2.1 谁黑谁白
优点 缺点 适用范围
方案一:用1个变量标识你是哪个玩家;再用1个变量标识哪个玩家是黑棋。 有玩家号码标识,可扩展性好 游戏其它功能需要跟玩家编号有关联时可用该方案。
方案二:用1个变量标识你是黑棋或白棋。 只需要1位(bit)即可 因为玩家没有固定的玩家号码,所以可扩展性较差 不做扩展功能,只做最简洁的联机五子棋时可用该方案。
两个方案都是可以的,只是需要看实际场景。如果你只想做个简单的五子棋,用方案二就够了。如果考虑扩展性,推荐方案一。
2.2 游戏结束了吗?谁赢了?该谁下棋了?
优点 缺点 适用范围
方案一:用1个变量标识游戏状态。黑赢、黑输、该玩家1下棋、该玩家2下棋等都是一种状态。 少了运算过程,快了几十毫秒。游戏状态的可扩展性好,可以新增状态(例如认输、悔棋等) 游戏会有多种状态时可用该方案。
方案二:只记录场上棋子的分布情况,通过计算是否有5连珠,判断谁输谁赢。 占用空间少 若要支持认输,只能回到方案一。 不做认输功能,只做最简洁的联机五子棋时可用该方案。
两个方案都是可以的,只是需要看实际场景。如果你只想做个简单的五子棋,用方案二就够了。如果考虑扩展性,推荐方案一。
2.3 悔棋
悔棋有2种形态:
  1. 请求悔棋后,无需对方确认,直接悔棋。
  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 噢~我有空了会分享做游戏的相关技术。

    推荐阅读