def successors(game_state): """Return a dict of {state:action} pairs. A state is a (wizard, boss, timed_effects) tuple, wizard: (hit_points, armor, mana); boss: (hit_points)""" result = {} w, b, in_use_spells_state = game_state spells_in_use = [name for name, timer in in_use_spells_state if timer > 1] # apply_effects gets callend once before launch spell is called # this clears up spells that have just timer=1 left spells = [magic_missile, drain, shield, poison, recharge] available_spells = [s for s in spells if s().name not in spells_in_use] for available_spell in available_spells: boss = Boss(damage=boss_damage, hit_points=b) h,a,m = w wizard = Wizard(mana=m, hit_points=h, armor=a) gs = GameState(wizard, boss) candidate_spell = available_spell() # restore timed spells for name, timer in in_use_spells_state: gs.spells.append(get_spell_by_name(name)(timer)) gs.apply_effects() if not boss.is_alive(): result[represent(gs)] = None # boss is killed by existing spells else: wizard.launch_spell(gs, spell=candidate_spell) if not wizard.is_alive(): continue if not boss.is_alive(): # boss killed by spell result[represent(gs)] = candidate_spell.name else: gs.apply_effects() if not boss.is_alive(): # boss killed by timed effect result[represent(gs)] = candidate_spell.name else: boss.attack(wizard) if wizard.is_alive(): result[represent(gs)] = candidate_spell.name return result
def action_cost(action): if not action: return 0 spell = get_spell_by_name(action)() return spell.cost
def successors_2(game_state): """Return a dict of {state:action} pairs. A state is a (wizard, boss, timed_effects) tuple, wizard: (hit_points, armor, mana); boss: (hit_points)""" result = {} w, b, in_use_spells_state = game_state spells_in_use = [name for name, timer in in_use_spells_state if timer > 1] # apply_effects gets callend once before launch spell is called # this clears up spells that have just timer=1 left spells = [magic_missile, drain, shield, poison, recharge] available_spells = [s for s in spells if s().name not in spells_in_use] # print game_state for available_spell in available_spells: boss = Boss(damage=boss_damage, hit_points=b) h,a,m = w wizard = Wizard(mana=m, hit_points=h, armor=a) gs = GameState(wizard, boss, level='hard') candidate_spell = available_spell() # print 'candidate_spell: %s' % candidate_spell.name # restore timed spells for name, timer in in_use_spells_state: gs.spells.append(get_spell_by_name(name)(timer)) gs.apply_effects('before_wizard') if not wizard.is_alive(): # can't happen at easy level # print 'wizard is dead by hard level 1' # print represent(gs) continue if not boss.is_alive(): # if boss dies by existing effects it is not necessary to add # a new spell result[represent(gs)] = None # boss is killed by existing spells else: # here boss is alive wizard.launch_spell(gs, spell=candidate_spell) if not wizard.is_alive(): # print 'wizard is dead launching spell' # print represent(gs) continue if not boss.is_alive(): # boss killed by spell result[represent(gs)] = candidate_spell.name else: gs.apply_effects('before_boss') if not wizard.is_alive(): # print 'wizard is dead by hard level 2' # print represent(gs) continue if not boss.is_alive(): # boss killed by timed effect result[represent(gs)] = candidate_spell.name else: boss.attack(wizard) if wizard.is_alive(): # if wizard is alive I log the launched spell # or else I don't care about this state result[represent(gs)] = candidate_spell.name return result