关于雀魂公平性与“牌山声明”的思考

最近开始玩雀魂了。我也就自然而然地开始考虑:对于这种运气成分很重的游戏,怎样保证运营方公平对待玩家、不因为猫粮购买量控制胜率?现在CRT这样的高水平赛事也在雀魂上举办了,运营能否干预比赛结果就更为重要。我们先看看雀魂现在是怎么做的,以下内容摘自萌娘百科

雀魂保证游戏生成完全随机,在游戏开始之时牌山序列已经固定,不会根据场面情况针对性地发牌。为证明此声明,游戏引入了MD5码验证系统。MD5码被广泛的应用于加密解密技术,它通过一个固定的算法把输入的字节(牌山序列)转化成一个字符串码。MD5码具有单向性、唯一性和混沌性的。

对局中,玩家可以点击左上角的宝牌位置查看本次对局牌山生成MD5码并记录下来。MD5码是每一次配牌生成一次的。对局结束后,玩家可以在牌谱中对照每一个小局的MD5码是否相同。以此验证游戏中给的MD5码没有给错。

本文引自萌娘百科(https://zh.moegirl.org),文字内容默认使用《知识共享 署名-非商业性使用-相同方式共享 3.0》协议。

的确,MD5验证牌山代码可以保证发牌姬不会在对局中针对性地发牌,但是它忽略了另一个问题:

如果运营想给玩家发个天和四暗刻单骑怎么办?

换言之,这个系统还是不能保证运营没有控制玩家手牌好坏、从而操作一局甚至一场比赛的结果。个人来说,我愿意相信猫粮没有这么做。但当你考虑密码学问题(都上MD5了),信任就只能基于“技术上不可行(一般指算力不足)”了。

于是我们希望解决的问题是:怎样让玩家相信运营没有控制牌山?我第一时间想到的是这样的一个协议:

  1. 公开由随机数种子生成牌山的代码,公开一段长字符串(app)。
  2. 在每局的开始时,生成一个随机数X。向玩家公开 SHA256(X),并把 SHA256(X||app) 作为种子生成牌山。
  3. 在对局结束时公开 X。玩家可以验证两个哈希值和牌山生成过程。

这样做保证了运营不能刻意构造一个牌山,因为即使可以从牌山倒退回需要的种子(这已经很难了,尤其是代码需要被公开审查的情况下),也无法从种子推出 X但是,运营可以用一台小霸王不停生成牌山并保存符合某些条件(比如天和)的 X 日后使用。因此这个协议也并不完美。

这里的问题是,运营仍然可以选择 X。于是我们可以稍微修改一下“生成一个随机数X”这一步:由每一个玩家(客户端)生成一个随机数,最终 X 为这些随机数拼接后的SHA256哈希值。游戏后,玩家们(尤其是比赛场)可以线下验证各自的随机数。

当然这个协议也只是一时兴起的产物,可能有其他问题,不知各位看官有什么想法。

另外,在密码学中有一个有趣的问题:怎样让两个人通过电话打扑克,同时保证公平性?利用这个问题的解法,应该可以设计一个由客户端负责合作洗牌的协议。这就留给读者作为练习了(?)