我在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,我想使,例如,当distanceToRing为1,000,000时,ITEM_SIZE_SMALL最常见,而当distanceToRing为10,000时,最不常见。我还希望ITEM_SIZE_LARGE与其相反,ITEM_SIZE_MEDIUM在中间更常见。至于项目类型,我需要ITEM_TYPE_FIRE和ITEM_TYPE_ICE最常见的1,000,000。对于10,000,ITEM_TYPE_WIND和ITEM_TYPE_EARTH应该更常见。
我知道要提出这个问题很多,但是如果你能提出一种处理这种分配的方法并解释它,我认为我可以解决它。另外,我因为缺乏Python技能而提前道歉。我没有长时间使用它来理解最佳实践甚至一些基础知识。
谢谢你的时间, 布赖恩
答案 0 :(得分: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))]
...
itemSize = get_random_size(distanceToRing)