理论篇五: 如何设计游戏棋牌平台 - 服务端 - 棋牌设计 - 一切皆步骤

整体架构图

整体架构图

之前几篇简单介绍了游戏中心这边的整体架构,关于后台中心的暂时不过多的介绍了。 今天开始进入棋牌设计阶段。

一切皆步骤

无论是竞技棋牌类的或是回合制类的游戏,甚至是很多其他类型的游戏,都可以用步骤来表示。

什么是步骤

步骤是连续性的,每个操作就是一个步骤,多个步骤聚集起来汇聚成一个步骤表

举个简单的例子

场景:
拉登的灯泡坏了,需要换灯泡。
(当然,不要给我说找不到可用的新灯泡怎么办,也不要给我说拉登不会换灯泡之类的。)

stepId: 1 - 寻找可用的新灯泡
stepId: 2 - 取下损坏的灯泡
stepId: 3 - 将新灯泡安装上

以上的每一个操作都代表一个步骤,所有步骤汇聚起来就是步骤表(这里一共 3 个步骤)。
步骤在麻将牌局中的例子

场景:
麻将牌局

stepId: 1 - 系统 [定庄] - 东 
stepId: 2 - [发牌] 总数: 108
stepId: 3 - 东 [接收牌总数:13] 1万 , 2万 , 3万 , 4万 , 5万 , 6万 , 7万 , 8万 , 9万 , 5万 , 5万 , 1万 , 1万 
stepId: 4 - 南 [接收牌总数:13] 1筒 , 2筒 , 3筒 , 4筒 , 5筒 , 6筒 , 7筒 , 8筒 , 9筒 , 5筒 , 5筒 , 1筒 , 1筒 
stepId: 5 - 西 [接收牌总数:13] 1条 , 2条 , 3条 , 4条 , 5条 , 6条 , 7条 , 8条 , 9条 , 5条 , 5条 , 3筒 , 3筒 
stepId: 6 - 东 [首次摸牌] 3筒 
stepId: 7 - 东 [出牌] 3筒 - 触发争议信息 {
位置: 南 - 玩家id: 2 - 最大争议等级: 41
可: (吃 - Lv:10) 牌列表: [1筒,2筒,3筒]  [2筒,3筒,4筒]  [3筒,4筒,5筒]  
位置: 西 - 玩家id: 3 - 最大争议等级: 41
可: (碰 - Lv:11) 
可: (胡 - Lv:41) 
}
stepId: 8 - 西 [碰] 东 3筒

这里的数据显示一共 7 个步骤 (步骤表)。
定庄、发牌,接收牌、摸牌、出牌都涉及到了。

其中步骤7 还包含了一些其他信息,其他玩家可对东打出的这张牌可以 吃、碰胡。

步骤在回合制游戏的例子

场景:
梦幻西游的战斗中,【龙太子 vs 剑侠客】

stepId: 1 - 龙太子 [龙鳞] - buff {龙太子:法术增强90% buff 有效时间3回合}
stepId: 2 - 剑侠客 [横扫千军] 龙太子 - buff {剑侠客:休息一回合buff}
stepId: 3 - 龙太子 [龙腾] 剑侠客
stepId: 4 - 龙太子 [龙腾] 剑侠客 - 信息 {剑侠客倒下}

步骤的优势

步骤对象类图 UML

步骤对象的类图 步骤相关!步骤对象-class_0

该步骤对象适用于任何竞技类的棋牌 
如:
麻将、跑胡子、扑克。
比如扑克类的就更简单、可以把争议信息对象属性移除(关于争议,后面的博客会介绍)。

步骤对象的属性:
存放多个牌列表 - 可以存放 
例如: 
扑克类 - 斗地主的飞机、顺子、炸弹等
麻将类 - 顺子
跑胡子 - 顺子
步骤表图 - 内存图

步骤表图内存图

断线重连时,直接把整个步骤表扔给游戏端即可还原牌局

不必每次都扔整个步骤表:
假设 游戏端 SQLite or cookie 会保存一些步骤信息. 
比如: 
当前牌局总步骤数是 33 步。
但玩家在第 31 步的时候断线了,那么参数stepId传入 31,
只需要恢复 2 个步骤就可还原牌局, 就不必传输所有步骤数据)
还原牌局
将牌局内的每一个操作都是一个步骤, 方便问题的追踪,牌局的状态还原。

比如在断线重连时
断线重连就会涉及到牌局的还原、玩家当前的状态等。
通过步骤表可以计算出:
1. 当前牌局中谁是庄家
2. 总牌数 (由总牌数可以计算出牌桌上的剩余牌数)
3. 当前轮到谁操作了
4. 每个玩家的倒牌区(克子、顺子、杠子)的牌都有哪些
5. 每个玩家的剩余手牌
6. 出牌区都有哪些牌
7. 如果步骤 id 不是连续性的可以进行牌局同步
8. 保证牌局的业务数据的原子性、连续性

断线重连时,将整个步骤表发送至重连的客户端中。
整个步骤表服务端只需要将敏感信息进行过滤(例如其他玩家的摸牌),在发送至客户端。
由客户端根据步骤表中的数据进行计算,得出最后的牌局状态(状态同步),进行绘制界面。

断线重连注意点:
把敏感信息移除。
什么是敏感信息,比如其他玩家的摸牌、暗杠等
也就是步骤对象中的 (敏感信息_关键张)赋值为 0 即可

步骤日志 UML

步骤日志格式化接口

通过步骤对象,可以很方便的进行日志格式化,甚至是定制个性化的日志

上图中给出了,碰、摸牌的步骤日志

所以步骤设计除了断线重连方便以外,牌局的操作日志也方便
步骤原子性

场景: 玩家进行碰的业务分别有:

  1. 移除手牌
  2. 将克子添加到倒牌区
  3. 将玩家操作状态切换为出牌
  4. 将数据添加到步骤中
如果在执行【碰】这个业务到 第3步的时候 (切换玩家状态为出牌),
程序突然奔溃了,那么整个业务将视为无效,需要重新执行业务(类似数据回滚)。
直到执行完成步骤,将数据添加到步骤中才算真正的完成。

步骤表可以保障游戏界面显示数据一致性
比如游戏中玩家没有接收到某个牌局操作消息, 如跳段了。
由于是步骤设计, 游戏端只需要检测 步骤 Id 不是连续性的,就可以进行一次同步,保障游戏内界面都拥有一致性数据。

结尾

如果大家有好的想法可以在评论留言或与我联系。
如果对该系列有兴趣,请大家给我们一点动力。我们的动力来源于点赞与收藏!
ok,今天先到这里!

转载于:https://my.oschina.net/iohao/blog/3067054

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值