10

45岁码农用不到2年时间撸出100款扑克游戏

 3 years ago
source link: https://gameinstitute.qq.com/community/detail/133491
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

扑克的玩法非常多,常见的就有斗地主、跑得快、五十K、锄大地、梭哈、十点半、二十一点、打千分、升级、拖拉机、双扣、保皇、斗牛、挖坑等等。在国内的不同地方,同类游戏的玩法也有不同讲究。粗略估计,国内的扑克玩法,超过上百种。

要短期内开发出这么多款扑克游戏,需要先对大多数扑克游戏进行系统的分析,归纳总结,然后打造一条流水线,每一款游戏都使用相同的框架,使用通用的零组件,等等。

本文主要内容就是讲述这个设计过程。

1.算法库

扑克游戏的历史很悠久,能够广为流行的一个原因就是上手比较容易。就算在今天,如果说一个人没读过书就学不会打扑克,这没人会相信。所以我估计扑克游戏的算法,都是比较简单的。归纳一下,一般包括:

  • 牌的大小(包括数字、花色等);牌的数目和分数;判断几张牌相同或连续;
  • 还需要一些对一组牌进行操作的算法,比如取出、合并等等。

基于以上的分析,我们估计可以完成一套通用的扑克的算法库,能满足所有扑克游戏。最后实践证明,扑克算法库比预期稍微复杂一点,但仍在可接受范围内。

此外,我们很容易发现,很多流行的手游的玩法、功能层出不穷,开发团队频繁升级迭代。相反,扑克游戏的玩法相对固定,演化相对较慢。所以,在系统设计上,我们假定扑克游戏的数量有限,玩法有限,发展慢。这样的好处是流水线设计好之后,以后改动很小,维护工作量也比较小。

2交互UI库

扑克游戏可以归纳出3个核心要素:牌、规则、人(玩家)。对扑克游戏的一种高度抽象的描述是:按照一定的流程和规则,每个人通过选择选项、选择牌、选择数值,来争取获胜的一种游戏。

归纳了一下,玩家的行为包括以下3种:

  • 对游戏流程中的选项,做出选择
  • 按照游戏规则,对牌进行选择。
  • 对数值(分数)进行选择。

比如斗地主中的叫地主、不抢,都是玩家自己要做的一种选择。出牌的时候选择不出,也是一种选择。后续会将“选项”称之为“命令”。

比如选择要出的牌,分组摆牌等。

比如下注。

以上三种玩家的行为,决定了游戏客户端需要提供哪些业务级UI库,对应下面几种:

  • 选牌或牌分组的UI
  • 选择数值的UI

由玩家选择其中一个按钮;在业务层,称为命令选择器

允许玩家在一组牌中选出符合要求的牌。牌分组UI则允许玩家将牌放入不同分组或按不同顺序排布。这2种在业务层都称为牌选择器

可以用滑动条,也有用按钮的。在业务层称为值选择器

以上我们抽象出了扑克游戏的3个核心要素,以及玩家使用的3类UI。现在我们思考一下扑克游戏还需要哪些UI。

除了牌、规则、人,实际上我们还需要房间(桌子)、椅子(座位)。

一款扑克游戏有很多界面、子界面;我们大体将其分为:房间内,房间外。房间内就是一个桌面,UI都显示到桌面上。房间外包括一些扑克游戏的常用界面和功能:注册、登录、用户信息;房间列表;查询(分数记录、排名等);其他比如:公告、帮助、设置。这些都可以做成通用的几套,不同游戏选择其中的一套即可。房间内除了3类选择器,还需要下面一些界面UI:座位、牌(比如公共牌、出牌)、定时器、图片(比如筹码)、文本(用于显示数值或文字)。这里除了一些业务级别的UI对象,也包含一些基础的UI对象。

3管理员与通讯库

现实中,几个朋友坐一桌打扑克的时候,每个人都按照流程和规则来,大家共同监督。而对于线上的扑克游戏,其实有一个规则执行者,不妨称之为管理员(我们前面将选项称之为“命令”,可以理解为:管理员下达出牌的命令,由玩家选择出牌还是不出。所以,“选项”是站在玩家角度,“命令”是站在管理员角度)。那么前文的说法,可以进一步升级为:扑克游戏就是由管理员控制一套流程规则,特定的时候交由玩家来选择选项、选择牌、选择值,这样一种竞赛游戏。这里我们引入了管理员的概念。

下面说通讯库:

几个朋友坐一桌打扑克的时候,比如发牌,每个人收到的牌,其他人不能看到;再比如一个人出牌,是要给其他人看到。现实中打牌,我们是靠视觉来看,相当于靠光线传播数据(图像),而对于网络游戏,则需要的是一个通讯库通过网络传输数据。我们不能仅仅提供一个简单的基于socket、websocket、http封装(比如常见的封装接口有 read_cmd,read_version,read_int,read_string....),这太底层了,我们需要的是一个业务级别的通讯库。

比如你跟你老婆说:晚上加班要11点回去,你老婆说“好的”。通讯库应该是这样的:

创建一问一答的异步请求,发给老婆;

请求分类是告假(晚上晚回);参数是11点;

答复选项是3种:好的;不行;超时;(如果你老婆不是话痨的话)

    再比如人事部给每个员工发短信,内容是本月工资明细。通讯库就是群发短信,格式相同,但内容不同。

通过分析一些扑克游戏,我们从这样几个层面进行设计抽象:通讯方向、是否应答、发送目标、单发还是群发。其中:不需要答复的,我们叫通知;需要答复的,我们叫“命令”或“请求”。从客户端发向管理员,称之为“客户端请求”;从管理员向客户端发送,称之为“服务端命令”;最终,我们把通讯归纳成5种模板:客户端请求;服务端命令;服务端广播;服务端私有通知;服务端公开通知;

有了通讯库,我们需要往里面塞数据,数据包括:通讯类型名称、命令选项、数值、牌。实际上数据内容也正是对应了选择选项、选择牌、选择数值

举个例子:比如轮到一个玩家出牌了,我们使用服务端命令定义了一个出牌命令,这是一问一答的通讯,管理员发送时,不携带数据。客户端答复时,选项包括:出、不出;如果出牌,则需要携带出的牌。

再举一个例子:游戏结束时需要通知输赢,这时可以使用服务端公开通知,就是服务端给每一个玩家发送通知,通知内容是这一局输了还是赢了,赢了多少金币。那么,这个通讯中,携带的就是赢的金币(如果为负值,则表明是输)

总结一下:套用这5种模板,通过定义名称、携带的数据,来定义游戏中特定的通讯过程。比如拖拉机游戏中有以下几种通讯的定义:发牌公开通知、亮主请求、亮主结果广播、扣底牌命令、扣底牌通知、出牌命令、出牌结果广播、结算通知。此外所有游戏都会用到一些公共的通讯定义:坐下请求、站起请求、一局开始广播、一局结束广播、聊天等。

在通讯中,还涉及到数据对不同客户端的可见性的问题,这里就不再深入介绍了。

通过分析数十款不同特点的扑克游戏,整理了下面一种思路:

所有扑克游戏,在概念上,可以这样划分:

  • 一局
  • 阶段
  • 一轮

比如斗地主,从发牌,到出牌,到结束,这是一局。一局结束后,开始下一局。

一局游戏可以划分成几个阶段,比如发牌阶段,出牌阶段,结算阶段;

大多数扑克游戏都是每个人轮着来的。还有一些游戏(或者游戏中的某个环节)是允许抢先的(比如拖拉机的亮主)。在技术上,一轮就是一个异步循环,提供很多参数和控制。

以上是为了方便而从概念上划分的,并不绝对,使用这样一种套路,开发不同扑克游戏时,可以更加统一了。

到目前为止,我们已经完成了下面的成品模块、框架、零组件。

  • 一套扑克算法库
  • 房间内的UI库
  • 房间外的几套成品模块
  • 5种通讯类模板

命令选择器;牌选择器;值选择器;头像、牌、图片、文本;

注册、登录、用户信息;房间列表;查询(分数记录、排名等);其他比如:公告、帮助、设置。

客户端请求;服务端命令;服务端广播;服务端私有通知;服务端公开通知;

提供一局、阶段、一轮等控制;

对于不同扑克游戏,我们首先要把游戏玩法弄清楚,然后用这些成品模块、框架、零组件,通过配置,通过编写一些代码来进行粘合,从而实现一个完整的游戏。

在实际的开发过程中我们验证了:对于简单的游戏,三五天就可以完成,对于极其复杂的游戏,一般在1~2周(比如拖拉机这类游戏)。这里说的是一个人,同时也包含自测时间。

为了提升粘合的效率,开发一个图形化编程工具,这里附上一些截图供参考:

  • 牌型算法的例子
tt1jEq6FW6Bs7KWqyok9.png


FSaiHqHKKGVhh6F8IVV2.png

    除了算法库、UI库以外,还包含了编程语言级别的函数、流程控制函数等。

cmREFjNAZDx46abfv9bD.png

有了这个工具,写牌型算法就快多了。

RDnx5dIoZprRXoIBjejo.png

这个图中的例子,包括了对一副牌进行洗牌,每次取出17张牌,在一个循环中,给每一个玩家发牌。下面是用英文显示函数的样子:

zlBhBHh8oc7F3ad1E7SN.png

    实际使用过程中,还是习惯英文编程。切换到中文相当于看看文档。

3ZoY12u38vD2u7Q1I7Tz.png

调试的时候,可以随时看一组牌是什么牌,这样很方便,对开发效率的提升很明显。

    以上介绍的图形化开发工具,已经具备的工程管理、图形化编程(编辑)、调试、发布、以及界面设置等辅助功能为一体的集成化开发环境。是图形化编程的一次有益的尝试。

技术人员自己可以搞定的测试是:单元测试;功能测试;性能测试(压力测试);

我们还请了专业的测试团队进行了游戏内测。

简单的公测:找老家亲戚朋友拉微信群,有些朋友人脉广,可以拉很多人。然后每天集中半小时搞一次测试,玩5局发10元红包,连续测试一周就差不多了。这种测试还挺有效,而且投入不大。

目前,项目已经基本达成了技术目标,所有扑克游戏使用了同一套算法库(C++代码使用emscripten 转为 javascript)、同一套UI库(html5/pixi.js)、两套标准的大厅,同一个服务器程序(C++),同一套通讯库(javascript)。另外还有:管理和监控后台;服务器更新;客户端更新;html5错误上报;C++错误上报等等。

除C++代码未开源,其他代码都开源了,文档齐全,放在 gitee上了,欢迎大家下载使用,欢迎提意见和交流。

(在html5浏览器兼容性方面有一些问题,比如UC浏览器、搜狗浏览器,特别需要熟悉这块的同学能给与一些支持!)

gitee.com/szcuipeng/public

       作者是9年前误入游戏行业,也有幸在一家上市游戏公司担任技术副总监,并承担过游戏引擎主程的工作。其实我不是很喜欢棋牌游戏开发,如果有机会,我更想去加入古剑或河洛的团队中去学习。我大学出来后大部分时间里,从事的是GIS(地图编辑、空间分析、图形)开发,也有一部分跟AutoCAD有关,都是windows客户端。一个团队40多号人,开发企业用大型客户端,当时在国内也颇为壮观。现在看到米国禁止咱们大学用MATLAB,我也很想投入到这些领域中。

自己一直喜欢干技术,虽然早已是大龄,但也一直坚持干技术,是因为从大学时候起,就想在技术上干出一点名堂来。那时自己仰望一些技术大牛,就像小虾米仰望14本天书中的大侠一样,希望有一天像他们一样,成为技术界的侠之大者,成为对社会对行业有用的人。

风马 2020年7月


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK