From f919dc99ab626a14a7b086d32ef451f9b832746f Mon Sep 17 00:00:00 2001 From: Darren Ranalli Date: Sat, 29 May 2004 02:46:07 +0000 Subject: [PATCH] added arg for pre-computed sum for weightedChoice --- direct/src/directutil/WeightedChoice.py | 5 +++++ direct/src/level/DistributedLevelAI.py | 6 ++---- direct/src/showbase/PythonUtil.py | 24 ++++++++++++++---------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/direct/src/directutil/WeightedChoice.py b/direct/src/directutil/WeightedChoice.py index 3038a32947..61da126b7a 100755 --- a/direct/src/directutil/WeightedChoice.py +++ b/direct/src/directutil/WeightedChoice.py @@ -1,6 +1,11 @@ import random +# DCR: I added a weightedChoice() function to PythonUtil that supports +# floating-point weights and is intended for one-shot choices. It +# has an optional 'sum' argument that you can pass in if you know the +# sum of the weights and want to make repeated choices. + class WeightedChoice: def __init__(self, listOfLists, weightIndex=0): t=0 diff --git a/direct/src/level/DistributedLevelAI.py b/direct/src/level/DistributedLevelAI.py index e783fb112f..01a7a33dbe 100755 --- a/direct/src/level/DistributedLevelAI.py +++ b/direct/src/level/DistributedLevelAI.py @@ -6,8 +6,7 @@ import DistributedObjectAI import Level import DirectNotifyGlobal import EntityCreatorAI -import WeightedChoice -from PythonUtil import Functor +from PythonUtil import Functor, weightedChoice class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI, Level.Level): @@ -74,8 +73,7 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI, # make list of lists: [(weight, scenarioIndex), ...] lol = zip([1] * levelSpec.getNumScenarios(), range(levelSpec.getNumScenarios())) - wc = WeightedChoice.WeightedChoice(lol) - scenarioIndex = wc.choose()[1] + scenarioIndex = weightedChoice(lol) Level.Level.initializeLevel(self, self.doId, levelSpec, scenarioIndex) diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index 3fa4ca4da7..c7090cce27 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -841,20 +841,24 @@ def mostDerivedLast(classList): return result classList.sort(compare) -def weightedChoice(choiceList, rng=random.random): - """given a list of (probability,item) pairs, chooses an item based on the - probabilities. rng must return 0..1""" - sum = 0. - for prob, item in choiceList: - sum += prob +def weightedChoice(choiceList, rng=random.random, sum=None): + """given a list of (weight,item) pairs, chooses an item based on the + weights. rng must return 0..1. if you happen to have the sum of the + weights, pass it in 'sum'.""" + if sum is None: + sum = 0. + for weight, item in choiceList: + sum += weight + rand = rng() accum = rand * sum - for prob, item in choiceList: - accum -= prob + for weight, item in choiceList: + accum -= weight if accum <= 0.: return item - # rand must be ~1., and floating-point error prevented accum from - # hitting 0. Return the last item. + # rand is ~1., and floating-point error prevented accum from hitting 0. + # Or you passed in a 'sum' that was was too large. + # Return the last item. return item def randFloat(a, b, rng=random.random):