Created
December 23, 2015 13:14
-
-
Save cnorthwood/52533b686357d4ae5d0b to your computer and use it in GitHub Desktop.
AoC day 22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import namedtuple | |
from itertools import count | |
from random import sample | |
PLAYER_HP = 50 | |
PLAYER_MANA = 500 | |
BOSS_HP = 71 | |
BOSS_DAMAGE = 10 | |
Spell = namedtuple('Spell', ['name', 'cost']) | |
Effect = namedtuple('Effect', ['name', 'turns']) | |
SPELLS = { | |
Spell('Magic Missile', 53), | |
Spell('Drain', 73), | |
Spell('Shield', 113), | |
Spell('Poison', 173), | |
Spell('Recharge', 229) | |
} | |
LOWEST_COST = min(spell.cost for spell in SPELLS) | |
def apply_effects(stats): | |
stats['player_armour'] = 0 | |
for (effect, turns) in frozenset(stats['effects']): | |
stats['effects'].remove((effect, turns)) | |
if effect == 'Shield': stats['player_armour'] = 7 | |
if effect == 'Poison': stats['boss_hp'] -= 3 | |
if effect == 'Recharge': stats['mana'] += 101 | |
if turns > 1: | |
stats['effects'].add(Effect(effect, turns - 1)) | |
def get_spell(): | |
return sample(SPELLS, 1)[0] | |
def player_wins(): | |
stats = { | |
'mana_spent': 0, | |
'mana': PLAYER_MANA, | |
'player_hp': PLAYER_HP, | |
'boss_hp': BOSS_HP, | |
'effects': set(), | |
'player_armour': 0 | |
} | |
while True: | |
stats['player_hp'] -= 1 | |
if stats['player_hp'] <= 0: | |
return False, stats['mana_spent'], "player killed by hard mode" | |
apply_effects(stats) | |
if stats['boss_hp'] <= 0: | |
return True, stats['mana_spent'], "boss dies through effects on our turn" | |
if stats['mana'] < LOWEST_COST: | |
return False, stats['mana_spent'], "out of mana" | |
spell, cost = get_spell() | |
while cost > stats['mana']: | |
spell, cost = get_spell() | |
while spell in [effect.name for effect in stats['effects']]: | |
# print spell, stats['effects'] | |
spell, cost = get_spell() | |
stats['mana'] -= cost | |
stats['mana_spent'] += cost | |
if spell == 'Magic Missile': stats['boss_hp'] -= 4 | |
if spell == 'Drain': | |
stats['boss_hp'] -= 2 | |
stats['player_hp'] += 2 | |
if spell == 'Shield': stats['effects'].add(Effect('Shield', 6)) | |
if spell == 'Poison': stats['effects'].add(Effect('Poison', 6)) | |
if spell == 'Recharge': stats['effects'].add(Effect('Recharge', 5)) | |
if stats['boss_hp'] <= 0: | |
return True, stats['mana_spent'], "boss dies through spell" | |
apply_effects(stats) | |
if stats['boss_hp'] <= 0: | |
return True, stats['mana_spent'], "boss dies through effects on their turn" | |
stats['player_hp'] -= max(BOSS_DAMAGE - stats['player_armour'], 1) | |
if stats['player_hp'] <= 0: | |
return False, stats['mana_spent'], "player killed by boss" | |
return False, stats['mana_spent'] | |
winning_costs = set() | |
for i in count(): | |
if i % 10000 == 0: print str(i), "rounds, lowest mana cost:", min(winning_costs or [0]) | |
wins, cost, reason = player_wins() | |
if wins: | |
winning_costs.add(cost) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment