示例#1
0
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
# -*- coding: utf-8 -*-

if __name__ == '__main__' and __package__ is None:
    from os import sys, path
    sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))

from game.spells import magic_missile, drain, shield, poison, recharge
from game.characters import Boss, Wizard
from game.strategies import SelectSpellByPredefinedOrder
from game.game_state import combat

def hit_armor_mana(wizard):
	return (wizard.hit_points, wizard.armor, wizard.mana)

mock_order = [poison(), recharge(), magic_missile(), magic_missile(), poison(), shield(), magic_missile(), magic_missile()]
wizard = Wizard(hit_points=50, mana=500, spell_selection_strategy=SelectSpellByPredefinedOrder(mock_order))
boss = Boss(hit_points=51, damage=9)

combat(wizard, boss)
assert not boss.is_alive()
assert wizard.is_alive()

# SOLUTION
[((50, 0, 500), 51, frozenset([])),
('Poison', 173), ((41, 0, 327), 48, frozenset([('Poison', 5)])),
('Recharge', 402), ((32, 0, 199), 42, frozenset([('Poison', 3), ('Recharge', 4)])),
('Magic Missile', 455), ((23, 0, 348), 32, frozenset([('Poison', 1), ('Recharge', 2)])),
('Magic Missile', 508), ((14, 0, 497), 25, frozenset([])),
('Poison', 681), ((5, 0, 324), 22, frozenset([('Poison', 5)])),
('Shield', 794), ((3, 7, 211), 16, frozenset([('Poison', 3), ('Shield', 5)])),
('Magic Missile', 847), ((1, 7, 158), 6, frozenset([('Poison', 1), ('Shield', 3)])),
示例#3
0
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
示例#4
0
if __name__ == '__main__' and __package__ is None:
    from os import sys, path
    sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))

from game.spells import Effect, TimedEffect
from game.spells import magic_missile, drain, shield, poison, recharge
from game.characters import Boss, Wizard
from game.strategies import SelectSpellByPredefinedOrder
from game.game_state import GameState

def hit_armor_mana(wizard):
	return (wizard.hit_points, wizard.armor, wizard.mana)

# Now, suppose the same initial conditions, except that the boss has 14 hit points instead:
mock_order = [recharge(), shield(), drain(), poison(), magic_missile()]
wizard = Wizard(hit_points=10, mana=250, spell_selection_strategy=SelectSpellByPredefinedOrder(mock_order))
boss = Boss(hit_points=14, damage=8)
game_state = GameState(wizard, boss)

# -- Player turn --
# - Player has 10 hit points, 0 armor, 250 mana
assert hit_armor_mana(wizard) == (10, 0, 250)
# - Boss has 14 hit points
assert boss.hit_points == 14
# Player casts Recharge.
s = wizard.launch_spell(game_state)
assert s.name == 'Recharge'

# -- Boss turn --
# - Player has 10 hit points, 0 armor, 21 mana
assert hit_armor_mana(wizard) == (10, 0, 21)