[ create a new paste ] login | about

Link: http://codepad.org/iwY04MTf    [ raw code | fork ]

RiskAnalysis - Python, pasted on Sep 28:
# Copyright 2010 Perseid. All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without modification, are
# permitted.
# 
# THIS SOFTWARE IS PROVIDED BY Perseid ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


def tupleAdd(a,b):
    return tuple(map(lambda x:x[0]+x[1],zip(a,b)))

def armyLoss(aggressor, defender):
    aggressor = sorted(aggressor)
    defender = sorted(defender)
    if len(defender) == 1:
        if defender[0] >= aggressor[2]:
            return (1,0)
        else:
            return (0,1)
    else:
        result = (0,0)
        if defender[1] >= aggressor[2]:
            result = tupleAdd(result,(1,0))
        else:
            result = tupleAdd(result,(0,1))
        if defender[0] >= aggressor[1]:
            result = tupleAdd(result,(1,0))
        else:
            result = tupleAdd(result,(0,1))
        return result

def crossProduct(setList):
    result = [tuple()]
    for mySet in setList:
        newResult = []
        for x in result:
            newResult.extend(map(lambda y:x+(y,),mySet))
        result = newResult
    return result

#for (aggr,defe) in crossProduct([crossProduct([range(1,7),range(1,7),range(1,7)]), crossProduct([range(1,7),range(1,7)])]):
    #print((aggr,defe))
    #print(armyLoss(aggr,defe))

partialAggrDices = sorted(list(set(
    map(lambda x:tuple(sorted(x)) ,crossProduct([range(1,7),range(1,7)]))
    )))

#2 Dice
TwoDiceAverage=dict()
for aggr in partialAggrDices:
    fullDefeDices = crossProduct([range(1,7),range(1,7)])
    results = map(lambda defe:armyLoss((1,)+aggr,defe),fullDefeDices)
    sum = (0,0)
    for result in results:
        sum = tupleAdd(sum,result)
    average = (float(sum[0])/len(fullDefeDices), float(sum[1])/len(fullDefeDices))
    #print (aggr,average)
    TwoDiceAverage[aggr] = average

#1 Dice
OneDiceAverage=dict()
for aggr in partialAggrDices:
    fullDefeDices = [[i] for i in range(1,7)]
    results = map(lambda defe:armyLoss((1,)+aggr,defe),fullDefeDices)
    sum = (0,0)
    for result in results:
        sum = tupleAdd(sum,result)
    average = (float(sum[0])/len(fullDefeDices), float(sum[1])/len(fullDefeDices))
    #print (aggr,average)
    OneDiceAverage[aggr] = average


#print("\n\n")
def bestStratArmyLoss(aggr):
    global OneDiceAverage
    global TwoDiceAverage
    aggr = tuple(sorted(aggr))
    aggr = (aggr[1],aggr[2])
    (a,d) = OneDiceAverage[aggr]
    OneDiceDiff = a-d
    (a,d) = TwoDiceAverage[aggr]
    TwoDiceDiff = a-d
    if OneDiceDiff > TwoDiceDiff:
        return OneDiceAverage[aggr]
    else:
        return TwoDiceAverage[aggr]

print(
"""'1 Die diff' is the average amount of armies the aggressor loses minus 
the average amount of armies the defender loses, if the defender rolls 
1 die.
'2 Dice diff' is the average amount of armies the aggressor loses minus 
the average amount of armies the defender loses, if the defender rolls 
2 dice.

A (x,y) battle loss means that the aggressor looses an average of x armies 
and the defender looses an average of y armies.

""")


for aggr in partialAggrDices:
    (a,d) = OneDiceAverage[aggr]
    OneDiceDiff = a-d
    (a,d) = TwoDiceAverage[aggr]
    TwoDiceDiff = a-d
    advice=""
    if OneDiceDiff > TwoDiceDiff:
        advice = "Use 1"
    else:
        advice = "Use 2"
    print("Aggressor dice: {0} ->  1 Die diff: {1: .4f};  2 Dice diff: {2: .4f}  =>   {3}: it results in ({4[0]:.4f},{4[1]:.4f}) battle loss.".format(aggr,OneDiceDiff,TwoDiceDiff,advice,bestStratArmyLoss((1,)+aggr)))

    #print("Aggressor dice:", aggr, " ->  1 Die diff:",OneDiceDiff, ";  2 Dice diff:", TwoDiceDiff," =>  ",advice,";  results in", bestStratArmyLoss((1,)+aggr), "battle loss")



averageBestStratLoss = (0,0)
for aggr in crossProduct([range(1,7),range(1,7),range(1,7)]):
    averageBestStratLoss = tupleAdd(averageBestStratLoss,bestStratArmyLoss(aggr))
#print(averageBestStratLoss)
print("\n\nThe average army loss is {:.4f} for the aggressor and {:.4f} for the defender assuming the defender plays the ideal strategy.".format(averageBestStratLoss[0]/6.0/6.0/6.0,averageBestStratLoss[1]/6.0/6.0/6.0))


Create a new paste based on this one


Comments: