0

这个问题的背景是:

  • 用于两人多人回合制纸牌游戏的 Google App Engine 后端
  • 游戏围绕着不同的卡片组合展开,从而在游戏中产生不同的分数

显然,可以将游戏的状态存储在 GAE 数据存储中,但我不确定游戏逻辑本身的设计方法。看来我可能有两个选择:

  1. 将条目存储在数据存储中,键是可以成为玩家的有效卡片组合的排序列表。然后这些将映射到分数值。当玩家尝试玩牌组合时,服务器端 python 将对组合进行适当的排序并查找密钥。如果成功,它可以对分数进行必要的更新,如果失败,则组合无效。

  2. 将有效组合存储为写入服务器端代码的 python 字典,并执行与上述相同的查找以测试有效性/获取分数,但无需访问数据存储。

从成本的角度来看(数据存储查找不是免费的),选项 2 似乎会更好。但是还有实例本身的性能——启动时间、处理时间、内存使用会开始让我付出更大的代价吗?

还有构建该 Python 字典的代码维护问题,但我可以将一些脚本组合在一起,以帮助我在不经常发生逻辑更改的情况下编写代码。如果这有助于任何想要量化问题的人,我认为将有大约 1000 张卡片组合(可以产生分数)在 2 到 6 张卡片之间。

我是从这个设计入手的,上面的总结是,将这种游戏的静态逻辑存储在datastore中,还是干脆将其作为CPU绑定逻辑的一部分,是否明智?两种方法的优缺点是什么?

4

2 回答 2

1

所以只是为了比较上面的信息:

在标准的一副牌中,有 52 张独特的牌。一手牌有 5 张牌,就有 2,598,960 种不同的手牌可供发牌。

    以下是组合数学的分解:

      n = 总共 52 张卡
      r = 5 手牌

    组合数 = n!/ (r! - (nr)!)
      = 52!/(5!* 47!)
      = (52 * 51 * 50 * 49 * 48) / (5 * 4 * 3 * 2 * 1)
      = 2,598,960

为了进一步简化示例,让我们将数字与 5 张牌梭哈扑克进行比较。扑克有 9 种不同类型的“得分”手(皇家同花顺、同花顺、四类、满屋、同花、顺子、三类、两对、一对)。

您手上没有任何东西的几率是 50.11% 您拥有上述任何组合的几率是 49.89%。

5 张牌梭哈中可能的手牌组合数量巨大,只有 4 套牌,牌上有 13 个数字,以及 9 种不同的“得分”组合类型

我希望这个例子清楚地说明了在数据库中生成和存储所有可能的 5 张牌梭哈的“得分”组合将是一项艰巨的任务。


这对您意味着什么:

由于我不知道您的游戏规则,因此您需要考虑的主要是不同“得分”组合类型的数量。

您并没有真正指定您可能的得分组合在游戏中的独特性/不同程度。组合类型的数量越接近组合的数量,自定义的“评分”规则就越多。

使用上面的 52 张卡片组示例,如果每只独特的手牌都有自己的独特分数,那么您将很快拥有超过 300 万个数据库条目。在这种情况下,我强烈建议您获得许多支持 MapReduce 查询功能的数据库(例如 Cassandra + Hadoop),这将允许您轻松扩展基础架构以减少查询时间。我想拥有 300 万个独特的得分组合是不太可能的。这会使游戏规则变得极其复杂,并可能使您的游戏无法玩。

既然您说您的游戏将有大约 1000 种 2-6 张牌的手牌组合,让我们简化示例并获得一个大致数字。使用尽可能多的手(6 张牌),在 12 张牌中可能有 3,003 手牌。假设不同组合类型、花色和编号卡的数量均匀分布(这里有一些幻想数学),您将看到大约 1,500 个“得分”组合。


底线:

为您的游戏“得分”获胜手所需的应用程序逻辑与您的游戏玩家需要理解才能玩游戏的逻辑完全相同(假设这个游戏需要任何技能/理解,它并不纯粹是靠运气)。越复杂,游戏对玩家来说就越难。我只能假设游戏逻辑没有那么复杂。

我发现你的牌组中不太可能只有 16 张牌。将几百张具有几种分组类型的牌用于唯一性似乎是合理的(例如扑克牌上的花色,或万智牌牌上的法术力类型)。假设您拥有比基本扑克游戏更多的牌和组合类型,那么似乎非常合理的结论是,存储各种组合比将游戏逻辑包含在代码中要花费更多的精力。此外,每次添加新规则时,您的存储需求都会以数量级增长,而不是线性扩展。

由于您将不可避免地开发实现纸牌游戏规则所需的代码,因此您不妨看看“得分”任意手牌需要多长时间。我会告诫不要过早优化,并建议您对设计进行原型设计。我建议您使用可配置的逻辑模块,让您可以根据需要轻松更改游戏规则。一旦规则得到巩固并且不太可能改变,那么我会根据需要考虑优化您的应用程序代码。从可维护性的角度来看,将所有应用程序逻辑存储在数据库中是疯狂的(我认为大多数维护程序员会同意我的观点)。在您尝试“修复”(例如,规范化、迁移、转换)由几个脚本生成的数据之后,您只是“拼凑在一起”

就 GAE 定价而言,您需要的实例数量将取决于您的用户/需求。通常,扩展系统的限制因素是磁盘 IOPS 而不是 CPU。从长远来看,我敢打赌,通过将所有应用程序逻辑存储在数据库中,您会对性能和定价产生更大的影响。


资料来源:

1)组合计算器: http: //www.calculatorsoup.com/calculators/discretemathematics/combinations.php

B) 扑克赔率:http ://www.durangobill.com/Poker.html

于 2013-09-15T03:07:36.417 回答
1

如果逻辑是固定的,请将其保留在您的代码中。也许您可以在启动时按程序生成字典。如果逻辑中有一个动态组件(您想经常更新的东西),那么数据存储可能是一个更好的选择,但听起来这在这里不适用。除非组合的数量超过数百万,并且您希望以速度换取更低的内存占用,否则请坚持将其放在应用程序本身中。

于 2013-09-14T22:49:12.933 回答