def main(): parser = argparse.ArgumentParser() parser.add_argument('target', type=float, help='desired probability of winning') parser.add_argument('d', **argdefs.d) parser.add_argument('--asides', **argdefs.asides) parser.add_argument('--dsides', **argdefs.dsides) parser.add_argument('--stop', **argdefs.stop) parser.add_argument('-v', '--verbose', **argdefs.v) args = parser.parse_args() log_level = {0: 'WARNING', 1: 'INFO'}.get(args.verbose, 1) log_fmt = '%(asctime)s - %(message)s' logging.basicConfig(level=log_level, format=log_fmt) logger = logging.getLogger(__name__) utils.clean_argparse(args) battle_args = dict(d=args.d, a_sides=args.asides, d_sides=args.dsides, stop=args.stop) min_troops = find_min_troops(args.target, battle_args, logger=logger) battle_args['a'] = min_troops win_prob = battle.calc_probs(**battle_args).win[-1] print(f'{min_troops} troops gives a win probability of {win_prob}')
def calc_prob(args, arg_idx, terr_idx, p_list): """Calculate the probability that will be minimized.""" new_args = deepcopy(args) new_args['d'][terr_idx] += 1 p = battle.calc_probs(**new_args).win[-1] p_list_new = p_list[:] p_list_new[arg_idx] = p if method == 'any': # Want to minimize the chance of losing in one or more configs. res = calc_any_win_prob(p_list_new) else: # Want to minimze the max probability. res = max(p_list_new) return res
def main(): """Spot check.""" args = dict(a=5, d=[3, 2], a_sides=[6, 6], d_sides=[6, 6], stop=1) battle_probs = battle.calc_probs(**args) args['iters'] = 50000 battle_probs_sim = battle.calc_probs_sim(**args) def print_probs(probs): for k, v in sorted(probs.items()): print(k, v) print('\nexact') print_probs(battle_probs.dist) print('\nsimulated') print_probs(battle_probs_sim.dist) print('\ncumulative probs (exact)') for i, probs in enumerate(battle_probs.cumul): print(f'----{["attack", "defense"][i]}----') for (k, v) in probs: print(k, v)
def battle_probs(config): return battle.calc_probs(**config.args)
def fortify(arg_list: List[Dict], d_troops: int, a_troops: int = 0, method: str = 'any') -> Fortified: """Fortify position to minimize chance of defeat. Args: arg_list (list of dicts): Contains config arguments. Note that any value that could take multiple values, like d, must be represented as a list d_troops (int): Number of troops to allocate to defensive territories a_troops (int): TODO method (str): One of two options: "weakest" or "any". "weakest": Minimize the maximum probability that you lose across configurations. Works better if you assume that the attacker will only attack in one engagement "any": Minimize the probability that you lose in *at least one* configuration. Works better if the attacker will attack in all engagements Returns: (Fortified) Battle args updated so that defensive positions have been fortified, along with some other descriptive info """ if a_troops > 0: raise NotImplementedError('argument `a_troops` not implemented') assert method in ['weakest', 'any'] arg_list_old = deepcopy(arg_list) # to include in output arg_list = deepcopy(arg_list) # we'll modify this going forward # @utils.memoize # can't use lru_cache b/c function args are not hashable def calc_prob(args, arg_idx, terr_idx, p_list): """Calculate the probability that will be minimized.""" new_args = deepcopy(args) new_args['d'][terr_idx] += 1 p = battle.calc_probs(**new_args).win[-1] p_list_new = p_list[:] p_list_new[arg_idx] = p if method == 'any': # Want to minimize the chance of losing in one or more configs. res = calc_any_win_prob(p_list_new) else: # Want to minimze the max probability. res = max(p_list_new) return res # Get list of attack winning in each battle config. p_list = [battle.calc_probs(**args).win[-1] for args in arg_list] # Iteratively add troops to the optimal positions. for _ in range(d_troops): best_arg_idx = None best_terr_idx = None best_p = 1 for arg_idx, args in enumerate(arg_list): for terr_idx in range(len(args['d'])): p = calc_prob(args, arg_idx, terr_idx, p_list) if p < best_p: best_p = p best_arg_idx = arg_idx best_terr_idx = terr_idx arg_list[best_arg_idx]['d'][best_terr_idx] += 1 p_list[best_arg_idx] = \ battle.calc_probs(**arg_list[best_arg_idx]).win[-1] fortified = Fortified(arg_list, arg_list_old, get_allocations(arg_list_old, arg_list), max(p_list), calc_any_win_prob(p_list), method) return fortified
def calc_prob(a): battle_args['a'] = a return battle.calc_probs(**battle_args).win[-1]