1

我正在 Twisted 的帮助下用 Python 编写游戏服务器。我有一个 Map 类,它为游戏生成地图。在我的游戏中,我有一个中心点,向外每隔一定距离放置一圈物品。我想随机化这些项目,但也要对项目进行加权,以便它们在地图外部更常见。目前这是我用于构建地图的代码,其中一些变量和函数名称已更改:

def generate():
    centralItem = Item(ITEM_TYPE_GOLD, 0, 0, ITEM_SIZE_GIANT, None)
    self.items.append(centralItem)
    distance = 10000
    numberOfRings = 100
    for ring in range(numberOfRings):
        itemsInRing = (ring + 1) * 100
        distanceToRing = (ring + 1) * distance
        for item in range(itemsInRing):
            angle = math.radians(float(360) / itemsInRing) * item
            xPos = math.cos(angle) * distanceToRing
            yPos = math.sin(angle) * distanceToRing
            # set variable itemSize using method described above (details below)
            # set variable itemType using method described above (details below)

我也有这个类,它带有一个用于创建项目的初始化程序。

class Item:

def __init__(self, type, posX, posY, size, owner):
    self.type = type
    self.posX = float(posX)
    self.posY = float(posY)
    self.size = size
    self.owner = owner

这些是我的定义。

ITEM_TYPE_FIRE = 0
ITEM_TYPE_ICE = 1
ITEM_TYPE_WIND = 2
ITEM_TYPE_EARTH = 3
ITEM_TYPE_GOLD = 4

ITEM_SIZE_SMALL = 200
ITEM_SIZE_MEDIUM = 350
ITEM_SIZE_LARGE = 500
ITEM_SIZE_GIANT = 1000

根据 generate 方法中的 distanceToRing,我想使 ITEM_SIZE_SMALL 在 distanceToRing 为 1,000,000 时最常见,而在 distanceToRing 为 10,000 时最不常见。我还希望 ITEM_SIZE_LARGE 与此相反,并且 ITEM_SIZE_MEDIUM 在中间更常见。至于项目类型,我需要 ITEM_TYPE_FIRE 和 ITEM_TYPE_ICE 最常见到 1,000,000。ITEM_TYPE_WIND 和 ITEM_TYPE_EARTH 应该更常见于 10,000。

我知道有很多问题要问,但如果你能提出一种处理这样的分发方式并解释它,我想我可以弄清楚。另外,我提前为我缺乏 Python 技能而道歉。我使用它的时间还不够长,无法理解最佳实践甚至一些基础知识。

谢谢你的时间,布赖恩

4

1 回答 1

2

显然,您需要准确确定每种物品类型/尺寸的概率与距离的关系。最简单的答案是制作一个三角形,其峰值位于您喜欢的位置和一致的范围(我会说 10000 到 1000000),如下所示:

item_sizes = [ITEM_SIZE_SMALL, ITEM_SIZE_MEDIUM, ITEM_SIZE_LARGE]

def get_item_weights(distance):
    return [1010000 - distance, 1000000 - abs((505000-distance)*2), distance]

这将为您提供 10000 的大部分小物品,1000000 的大部分大物品,以及中间大约 25/50/25 的拆分。也许你不喜欢这样的工作方式,但我无法知道。在构建随机过程时,可能需要反复试验才能找到您喜欢的东西。(从技术上讲,由于 505000 不是有效距离,中间权重将在 990000 处达到峰值,但我认为这并不重要,值得我花时间修复,尤其是因为你可能不喜欢这种分布。)

要选择给定重量的项目,我会做这样的事情:

import random

random.seed()

def get_random_index(weights):
    n = random.randint(1, sum(weights))
    cumsum = 0
    for index, weight in enumerate(weights):
        cumsum += weight
        if n <= cumsum:
            return index

def get_random_size(distance):
    return item_sizes[get_random_index(get_item_weights(distance))]

…</p>

itemSize = get_random_size(distanceToRing)
于 2012-07-23T01:39:05.323 回答