(Python) 平均分配数字

1 投票
2 回答
809 浏览
提问于 2025-04-18 13:07

抱歉这个标题不太好。如果有人能想出更合适的标题,请告诉我,我会重新发布这个问题或者修改标题(如果可以的话)。

你好,我现在正在开发一个游戏。当发起攻击时,攻击者可以从对方那里获得一定数量的资源。我现在遇到的问题是,如何在防守方有资源可以给的情况下,公平地分配这些资源给攻击者。

#this is how many resources the attacker can get, def's resources
attacker_potential = 250
#this is how many resources the defender has
defender.wood = 100
defender.iron = 25
defender.wheat = 76
defender.gold = 50000
#then the attacker would make off with 
attacker.wood += 75
attacker.iron += 25
attacker.wheat += 75
attacker.gold += 75

另一个例子:

defender.wood = 2500
defender.iron = 2500
defender.wheat = 5000
defender.gold = 5000
#here, the attacker would make off with 62 for each resource. (250 / 4 = 62.5)

这里还有一个例子:

defender.wood = 100
defender.iron = 0
defender.wheat = 1
defender.gold = 0
#attacker would make off with:
attacker.wood += 100
attacker.iron += 0
attacker.wheat += 1
attacker.gold += 0

最后一个例子:

defender.wood = 50000 #pretend the rest are 0
attacker.wood += 250 

(一旦我算出攻击者能得到多少资源,后面的计算就简单多了)。我刚到达代码的这一部分,花了大约20分钟试图弄清楚这个怎么实现。我觉得答案可能很简单。

2 个回答

3

根据你提供的例子,有一个算法可以这样理解:

  1. 首先,计算一下平均战利品,这个平均值是攻击者的潜力除以防守者的非零资源数量。然后,检查防守者的每一项非零资源,如果有任何一项小于或等于这个平均值,就把它从防守者那里移走,给攻击者。

  2. 如果在第一步中发现并移动了小于或等于平均战利品的资源,就重新计算一次平均战利品,然后再执行第一步。如果没有发现这样的资源,就直接进入第三步。

  3. 最后,如果防守者还有剩余的资源,就重新计算一次平均战利品,然后从每一项资源中移走这个平均值(也就是给攻击者)。

下面是一个可能的Python实现:

def step1(dres, aloot, potential):

    again = False

    ndres = {}

    if len(dres) > 0:

        avgloot = int(potential / len(dres))

        for r in dres:
            if dres[r] <= avgloot:
                potential -= dres[r]
                aloot[r] += dres[r]
                again = True
            else:
                ndres[r] = dres[r]

    return (ndres, aloot, potential, again)

def calculate_loot(dres, potential):

    aloot = {'wood':0, 'iron':0, 'wheat':0, 'gold':0}

    (dres, aloot, potential, again) = step1(dres, aloot, potential)

    while again:
        (dres, aloot, potential, again) = step1(dres, aloot, potential)

    if len(dres) > 0:
        avgloot = int(potential / len(dres))
        for r in dres:
            aloot[r] += avgloot

    return aloot

potential = 250

for dres in [
        {'wood':100,  'iron':25,   'wheat':76,   'gold':50000},
        {'wood':2500, 'iron':2500, 'wheat':5000, 'gold':5000 },
        {'wood':100,  'iron':0,    'wheat':1,    'gold':0    },
        {'wood':0,    'iron':0,    'wheat':0,    'gold':50000}
    ]:

    print(dres)
    print(calculate_loot(dres, potential))
    print(' ')

在线演示

0

轮询算法用于整数资源。如果你真的想要分配资源,可以检查一下剩余资源的总量是否小于资源的数量,如果是的话,就可以平均分配。

def distribute(potential, defender_resources):
    attacker_resources = [0] * len(defender_resources)

    while potential and any(defender_resources):
        for i in range(len(defender_resources)):
            if potential and defender_resources[i]:
                defender_resources[i] -= 1
                attacker_resources[i] += 1
                potential -= 1

    return attacker_resources

print distribute(250, [100,0,1,0])
print distribute(250, [100,25,76,5000])
print distribute(250, [2500,2500,2500,2500])
print distribute(250, [5000])

撰写回答