[教你做小游戏]《五子棋》怎么存棋局信息?(代码片段)

HullQin HullQin     2022-12-01     214

关键词:

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 噢~我有空了会分享做游戏的相关技术。

[教你做小游戏]用177行代码写个体验超好的五子棋(代码片段)

...戏的需求,你会怎么做呢?2.技术选型参考掘金文章《H5小游戏技术选型分析,低代码?小游戏框架?canvas或SVG?还能用React?》,我们利用文章的决策树进行技术选型:我们不需要借助现有的游戏模板。我们不需要素材管理、不涉及... 查看详情

[教你做小游戏]用86行代码写一个联机五子棋websocket后端(代码片段)

背景上篇文章《用177行代码写个体验超好的五子棋》,我们一起用177行代码实现了一个本地对战的五子棋游戏。现在,如果我们要做一个联机五子棋,怎么办呢?需求分析首先,我们需要一个后端服务。2个不同的玩家,一起连... 查看详情

[教你做小游戏]用svg画一个象棋棋盘

背景兄弟们,之前我开发了支持联机对战的五子棋、斗地主、UNO。在大家的呼吁之下,我准备开发「象棋」啦! 查看详情

💒es6+canvas开源盖楼小游戏完整代码注释从零教你做游戏(代码片段)

盖楼游戏一个基于Canvas的盖楼游戏Demo预览在线预览地址(DemoLink)手机设备可以扫描下方二维码githubhttps://github.com/bmqb/tower_game喜欢的朋友给个star支持一下哦GameRule游戏规则以下为默认游戏规则,也可参照下节自定义游戏参数每局游... 查看详情

[教你做小游戏]滑动选中!pc端+移动端适配!完美用户体验!斗地主手牌交互示范(代码片段)

背景之前我们提到了斗地主的最优秀的交互方案:《斗地主的手牌,如何布局?看25万粉游戏区UP主怎么说》。具体交互如下:PC端:未选中的牌,是默认状态;选中的牌,加一层半透明的黑色遮罩层。鼠标单击牌,可以选中牌。... 查看详情

[教你做小游戏]斗地主的手牌,如何布局?看25万粉游戏区up主怎么说

背景在B站拥有25万粉丝的UP主「时少权」,发布了条视频:《为什么中国10年都做不好斗地主?》,播放量直破10万,视频主要内容如下:十年来,几乎所有斗地主游戏展示手牌的方式(下称理牌方式)都千篇一律:手牌排列为一... 查看详情

unity实战:教你做黄豆君(代码片段)

文章目录前言一、Unity2D入门1.入门准备1.1导入开发所需要的资源1.2创建地形1.3改变地形颜色2.游戏中的2DCamera2.1了解Camera的基本属性2.2创建相机跟随脚本2.3把主角装载到照相机跟随脚本上3.物理碰撞系统3.1设置地形碰撞检测组件3.2... 查看详情

unity实战:教你做黄豆君(代码片段)

文章目录前言一、Unity2D入门1.入门准备1.1导入开发所需要的资源1.2创建地形1.3改变地形颜色2.游戏中的2DCamera2.1了解Camera的基本属性2.2创建相机跟随脚本2.3把主角装载到照相机跟随脚本上3.物理碰撞系统3.1设置地形碰撞检测组件3.2... 查看详情

unity实战:教你做黄豆君(代码片段)

文章目录前言一、Unity2D入门1.入门准备1.1导入开发所需要的资源1.2创建地形1.3改变地形颜色2.游戏中的2DCamera2.1了解Camera的基本属性2.2创建相机跟随脚本2.3把主角装载到照相机跟随脚本上3.物理碰撞系统3.1设置地形碰撞检测组件3.2... 查看详情

[教你做小游戏]展示斗地主扑克牌,支持按出牌规则排序!支持按大小排序!(代码片段)

问题描述我们想做一个斗地主游戏,其中最重要的一点是,把扑克牌展示出来。一副牌有54张,我们给每张牌1个编号(id),取值1-54。如果涉及到2副牌,就取id为1-108。展示牌,其实就是给你一个id列表,按需展示列表中的牌即... 查看详情

手把手教你做一个缓存工具(代码片段)

日常开发中,某些数据接口即使优化到极致,都难免还会存在计算量巨大导致响应过慢,多数情况单独做一个统计表用于存放这些处理后的数据用于读取,或者接入redis/memcache存数据,就是说单次响应本身是可以接受较慢一些的... 查看详情

520到了,教你做个javaweb表白墙小项目

目录1.配置Maven项目1.1创建Maven项目1.2引入相关依赖1.3项目总结构2.约定前后端交互接口3.服务端代码3.1 创建Message类3.2创建工具类3.3添加信息类(AddMessage)3.4查询信息类(MessageList)4.前端代码5.创建数据库6.部署项... 查看详情

javascript应用——手把手教你做一个页面化猜数字游戏

一听到猜数字游戏,想必大家都不太陌生吧?是的没错,很多人都用C语言或者Java写过猜数字游戏小程序,博主也不例外,之前写过C语言版本的猜数字游戏,感兴趣的同学可以看看C语言版本猜数字游戏。... 查看详情

unity实战:教你做黄豆君(代码片段)

文章目录前言一、Unity2D入门1.入门准备1.1导入开发所需要的资源1.2创建地形1.3改变地形颜色2.游戏中的2DCamera2.1了解Camera的基本属性2.2创建相机跟随脚本2.3把主角装载到照相机跟随脚本上3.物理碰撞系统3.1设置地形碰撞检测组件3.2... 查看详情

关于qt信号和槽机制的重复绑定错误及改正

  之前做过一个作业,是编写五子棋、围棋游戏,因为需要界面,所以选择了QT框架。Qt的核心机制之一是信号与槽,主要用来进行两个对象之间的通信。当一个对象状态改变时,可以发出一个信号,另一个对象则执行与这个... 查看详情

2018.10.4二连爆搜+再次出锅

T1:五子棋【题目描述】五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。五子连珠是在横线,纵线,... 查看详情

手把手教你做javaweb项目:登录模块

现如今,无论是客户端还是移动端,无论是电动登陆还是社交平台登陆,无处不在的“登陆”。那么你知道怎么制作吗?今天就为你娓娓道来:用户登录在各大信息管理系统中,登录功能是必不可少的,他的作用就是验证用户的身... 查看详情

手把手教你做项目多线程篇——基础知识详解(代码片段)

...互斥锁信号量送点资源导读随着暑假的推进,手把手教你做项目前边的准备也差不多了后续的项目也渐渐要开始了但是正式发出来可能要等一段时间前后端都是我一个人确实有点费力(毕竟我也是菜鸡),后面我... 查看详情