Advertisement
Guest User

Magic Combat Golf Example

a guest
Aug 26th, 2015
218
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python3
  2. import itertools
  3.  
  4.  
  5. # memoizes function calls, key = repr of input.
  6. class memoized(object):
  7.     def __init__(self, func):
  8.         self.func = func
  9.         self.cache = {}
  10.  
  11.     def __call__(self, *args):
  12.         args_repr = repr(args)
  13.         if args_repr in self.cache:
  14.             return self.cache[args_repr]
  15.         else:
  16.             value = self.func(*args)
  17.             self.cache[args_repr] = value
  18.             return value
  19.  
  20.  
  21. def best_block(attackers, blockers):
  22.     return max(block_sets(len(attackers), len(blockers)),
  23.                key=lambda opt: score(attackers, blockers, opt))
  24.  
  25.  
  26. def block_sets(a_len, b_len):
  27.     block_options = []
  28.     for b in range(b_len):
  29.         block_options.append([()])
  30.         for a in range(a_len):
  31.             block_options[-1].append((b, a))
  32.     return (list(list(o) for o in opt if o != ())
  33.             for opt in itertools.product(*block_options))
  34.  
  35.  
  36. def score(attackers, blockers, block_pairs):
  37.     blocked_by = {}
  38.     score = sum(sum(blockers, [])) - sum(sum(attackers, []))
  39.     for blocker, attacker in block_pairs:
  40.         if attacker not in blocked_by:
  41.             blocked_by[attacker] = []
  42.         blocked_by[attacker].append(blocker)
  43.     for index, attacker in enumerate(attackers):
  44.         power, toughness = attacker
  45.         if index in blocked_by:
  46.             cur_blockers = [blockers[b_ind] for b_ind in blocked_by[index]]
  47.             def_power = sum(def_pow for def_pow, def_tough in cur_blockers)
  48.             if def_power >= toughness:
  49.                 score += power + toughness
  50.             score -= att_score(power, cur_blockers)
  51.         else:
  52.             score -= power/2
  53.     return score
  54.  
  55.  
  56. @memoized
  57. def att_score(power, blockers):
  58.     toughnesses = [toughness for _, toughness in blockers]
  59.     if power >= sum(toughnesses):
  60.         return sum(sum(blockers, []))
  61.     elif power < min(toughnesses):
  62.         return 0
  63.     else:
  64.         results = []
  65.         for ind, blocker in enumerate(blockers):
  66.             p, t = blocker
  67.             if power >= t:
  68.                 new_blockers = blockers[:ind] + blockers[ind+1:]
  69.                 results.append(p+t+att_score(power-t, new_blockers))
  70.         return max(results)
  71.  
  72. att = eval(input("Attacking creatures: "))
  73. block = eval(input("Defending creatures: "))
  74.  
  75. best = best_block(att, block)
  76.  
  77. print("Blocks:", best)
  78. print("Initial score:", sum(sum(block, [])) - sum(sum(att, [])))
  79. print("Final score:", score(att, block, best))
Advertisement
RAW Paste Data Copied
Advertisement