2

我最近提出的关于 Python 的所有问题都是针对这个项目的。我已经意识到我问这么多问题的原因可能不是因为我对 Python 太陌生(但我对 PHP 有一点了解),也可能不是因为 Python 有一些固有的缺陷。

因此,我现在将说明项目是什么以及我目前的想法是什么,你可以告诉我我做错了,我需要学习一些东西,或者 Python 根本不适合处理这种类型在这种情况下,项目和语言 XYZ 会更好,甚至有一些我可能想参与的开源项目。

该项目
我运行一个免费的回合制策略游戏(想想全面战争系列中的战役模式,但更加复杂和深度),并正在为它创建一个战斗模拟器(再次,把全面战争看作是它的想法工作)。我绝不会自欺欺人地认为我会单独制作像全面战争游戏一样好的东西,但我确实认为我可以自动化我目前手工完成的过程。

它会做什么
它必须考虑到单位、设备、训练、天气、地形等的大量变量。我知道这是一项艰巨的任务,我计划在空闲时间一次完成。我的预算为零,但这是我准备投入时间(并且已经投入)的爱好。

我当前的绊脚石
在 PHP 中,一切都可以访问其他一切,“错误”,尽管有些人可能认为这真的很方便。如果我有一组设备供单位使用,我可以从任何地方获取该数组。使用 Python 时,每次导入相关数据文件时,我都必须重新制作该数组,这对于一种根据我的经验经过深思熟虑的语言来说似乎是一个非常愚蠢的解决方案。我已经建立了一个记录函数调用和类创建的系统(因为我从一个非常基本的版本中知道,我曾经在 PHP 中做过这将有很大帮助)以及我一直保持的方式一个地方的数据是将我的每个类传递一个实例到我的日志记录列表中,这对我来说就像一个黑客,但这是我让它工作的唯一方法。

因此,我得出结论,我错过了一些东西,并且非常感谢任何愿意提供它的人的洞察力。谢谢你。

代码示例

这会创建一个编队列表,到目前为止只有一个值(除了名称之外),但我预计会添加更多内容,这就是为什么它们是类列表而不仅仅是标准列表的原因。这可以在 data.py 中找到

formations = []
formationsHash = []
def createFormations(logger):
    """This creates all the formations that will be used"""

    # Standard close quarter formation, maximum number of people per square metre
    formationsHash.append('Tight')
    formations.append(Formation(logger, 'Tight', tightness = 1))

    # Standard ranged combat formation, good people per square metre but not too cramped
    formationsHash.append('Loose')
    formations.append(Formation(logger, 'Loose', tightness = 0.5))

    # Standard skirmishing formation, very good for moving around terrain and avoiding missile fire
    formationsHash.append('Skirmish')
    formations.append(Formation(logger, 'Skirmish', tightness = 0.1))

    # Very unflexible but good for charges
    formationsHash.append('Arrowhead')
    formations.append(Formation(logger, 'Arrowhead', tightness = 1))


def getFormation(searchFor):
    """Returns the fomation object with this name"""
    indexValue = formationsHash.index(searchFor)
    return formations[indexValue]

我没有何时需要访问它的代码示例,因为我还没有做到这一点,但我预计代码如下所示:

Python
tempFormation = data.getFormation(unit.formationType)
tempTerrain = data.getTerrain(unit.currentTerrain)
unit.attackDamage = unit.attackDamage * tempTerrain.tighnessBonus(tempFormation.tightness)

该单元包含一个整数,该整数链接到主列表中相关地形、地层和诸如此类的索引/键。临时变量用于使第 3 行更短,但从长远来看,如果我忘记获取一个并且它使用的是之前不正确的值,从长远来看可能会导致问题(这就是日志记录派上用场的地方)。

PHP
$unit->attackDamage *= $terrain[$unit->currentTerrain]->tighnessBonus($unit->currentTerrain)

单位类包含它所在的相关地形的索引(可能是一个字符串)以及它所在的地层。

也许这会在我对 Python 的理解中显示出一些巨大的缺陷(6 个月与 PHP 的 3 年)。

4

4 回答 4

5

每次导入相关数据文件时,我都必须使用 Python 重新制作该数组

您在这里错过了 Python 语义的一个微妙点。当您第二次导入一个模块时,您不会重新执行该模块中的代码。该名称可在所有导入的模块列表中找到,并将相同的模块返回给您。因此,第二次导入模块时,您将获得对同一列表的引用(在 Python 中,不要说数组,而是说列表)。

您可能需要发布特定的代码示例以获得更多帮助,似乎其中混杂了一些 Python 误解,一旦这些误解被清除,您将有一个更简单的时间。

于 2009-01-01T17:03:41.027 回答
3

我已将您的问题缩小到:

每次导入相关数据文件时,我都必须使用 Python 重新制作该数组

那么你真的有两个选择,第一个也是最简单的是将结构保存在内存中。这样(就像 PHP 一样)理论上你可以从“任何地方”访问它,你会受到命名空间的轻微限制,但这是为了你自己好。它将翻译为“您想去的任何地方”。

第二种选择是有一些数据抽象(如数据库或数据文件)来存储和检索数据。这可能比第一个选择更好,因为您可能有太多数据无法一次放入内存。再次获取这些数据的方式将像 PHP 一样“随处”可用。

您可以以显式方式将这些东西直接传递给实例,或者您可以使用模块级全局变量并将它们导入到您需要它们的地方,正如您继续说的那样:

我将数据保存在一个地方的方法是将我的每个类传递一个实例到我的日志记录列表

我可以向你保证,这不是黑客行为。这是相当合理的,取决于用途,例如配置对象可以以相同的方式使用,因为您可能希望同时使用不同的配置来测试您的应用程序。日志记录可能更适合作为刚刚导入和调用的模块级全局,因为您可能只需要一种日志记录方式,但同样,这取决于您的要求。

我想总结一下,你真的走在正确的轨道上。尽量不要屈服于那种“hackish”的味道,尤其是在使用你不完全熟悉的语言时。一种语言的 hack 可能是另一种语言的黄金标准。当然,祝你的项目好运——听起来很有趣。

于 2009-01-01T16:43:47.993 回答
3

请不要重新发明轮子。您formationsHash作为键值列表没有帮助,它复制了字典的功能。

def createFormations(logger):
    """This creates all the formations that will be used"""
    formations = {}
    formations['Tight']= Formation(logger, 'Tight', tightness = 1)
    formations['Loose']= Formation(logger, 'Loose', tightness = 0.5)
    formations['Skirmish']= Formation(logger, 'Skirmish', tightness = 0.1)
    formations['Arrowhead']= Formation(logger, 'Arrowhead', tightness = 1)
    return formations

请注意,您实际上并不需要getFormation,因为它对您没有好处。你可以简单地使用这样的东西。

formations = createFormations( whatever )
f= formations[name]
于 2009-01-01T19:12:45.447 回答
1

“data.py 创建了一个数组(嗯,列表),要从另一个文件中使用这个列表,我需要导入 data.py 并重新制作所述列表。”

我不明白你在说什么。严重地。

这是一个导入数据的主程序和另一个模块。

SomeMainProgram.py

import data
import someOtherModule

print data.formations['Arrowhead']
someOtherModule.function()

一些其他模块.py

import data
def function():
    print data.formations['Tight']

数据.py

import theLoggerThing
class Formation( object ):
    pass # details omitted.
def createFormations( logger ):
    pass # details omitted
formations= createFormations( theLoggerThing.logger )

所以主程序是这样工作的。

  1. import data. 模块已data导入。

    一种。 import theLoggerThing. 不管这是什么。

    湾。 class Formation( object ):. 创建一个类Formations

    C。 def createFormations( logger ):. 创建一个函数createFormations

    d。 formations =. 创建一个对象,formations

  2. import someOtherModule. someOtherModule是进口的。

    一种。 import data. 没发生什么事。 data已经在全球范围内可用。这实际上是对Singleton的引用。所有 Python 模块都是Singletons

    湾。 def function. 创建一个函数function

  3. print data.formations['Arrowhead']. Evaluate data.formations,它是一个字典对象。对字典执行 aget('Arrowhead')进行一些神奇的查找并返回在那里找到的对象(的实例Formation)。

  4. someOtherModule.function().

    在此函数评估期间会发生什么。

    一种。print data.formations['Tight']. Evaluate data.formations,它是一个字典对象。对字典执行 aget('Tight')进行一些神奇的查找并返回在那里找到的对象(的实例Formation)。

于 2009-01-01T19:35:40.533 回答