◂ 22 décembre 2015 ▸
Wizard Simulator 20XX :
- code.py
from pprint import pprint
from functools import cache
import itertools, math
SPELLS = tuple(map(lambda t:dict(zip(['name', 'cost', 'turns', 'damage', 'armor', 'heal', 'mana'], t)), [
['Magic Missile', 53, 0, 4, 0, 0, 0],
['Drain', 73, 0, 2, 0, 2, 0],
['Shield', 113, 6, 0, 7, 0, 0],
['Poison', 173, 6, 3, 0, 0, 0],
['Recharge', 229, 5, 0, 0, 0, 101],
]))
BOSS_POINTS = 71
BOSS_DAMAGE = 10
MY_POINTS = 50
MY_MANA = 500
SPELLS_TURNS = len(SPELLS) * (0,)
FAIL = -1
def applySpells(myPoints, myMana, bossPoints, spellsTurns):
myArmor = 0
for spellIndex in range(len(SPELLS)):
if spellsTurns[spellIndex] > 0:
spellsTurns[spellIndex] -= 1
spell = SPELLS[spellIndex]
bossPoints -= spell['damage']
myArmor += spell['armor']
myPoints += spell['heal']
myMana += spell['mana']
return (myPoints, myMana, bossPoints, myArmor)
# Trop long sans memoizing !
@cache
def getMinManaToWin(myPoints, myMana, bossPoints, spellsTurns, partie2 = False):
saveSpellsTurns = list(spellsTurns)
if (partie2):
myPoints -= 1
if myPoints <= 0:
return (FAIL, None)
# Spells at Player turn
(saveMyPoints, saveMyMana, saveBossPoints, saveMyArmor) = applySpells(myPoints, myMana, bossPoints, saveSpellsTurns)
minCost = None
minSpells = None
for spellIndex in range(len(SPELLS)):
spell = SPELLS[spellIndex]
if spell['cost'] > saveMyMana:
continue
if saveSpellsTurns[spellIndex] > 0:
continue
# reinit valeurs
(myPoints, myMana, bossPoints, spellsTurns) = (saveMyPoints, saveMyMana, saveBossPoints, saveSpellsTurns[:])
myMana -= spell['cost']
if spell['turns'] == 0:
bossPoints -= spell['damage']
myPoints += spell['heal']
myMana += spell['mana']
else:
spellsTurns[spellIndex] += spell['turns']
# Spells at Boss turn
(myPoints, myMana, bossPoints, myArmor) = applySpells(myPoints, myMana, bossPoints, spellsTurns)
if bossPoints <= 0:
theCost = 0
theSpells = []
else:
myPoints -= (max(1, BOSS_DAMAGE - myArmor))
if myPoints <= 0:
continue
(theCost, theSpells) = getMinManaToWin(myPoints, myMana, bossPoints, tuple(spellsTurns), partie2)
if theCost == FAIL:
continue
theCost += spell['cost']
if minCost == None or theCost < minCost:
minCost = theCost
minSpells = [spell['name']] + theSpells
if minCost == None:
return (FAIL, None)
else:
return (minCost, minSpells)
print(getMinManaToWin(MY_POINTS, MY_MANA, BOSS_POINTS, SPELLS_TURNS, partie2=False))
print(getMinManaToWin(MY_POINTS, MY_MANA, BOSS_POINTS, SPELLS_TURNS, partie2=True))