def test_attacker_wins_ties(self): a = Attacker(ship_die=1, combat_die_rolls=[1]) d = Defender(ship_die=1, combat_die_rolls=[1]) attacker_wins = a.attack(d) assert a.total() == 2 assert d.total() == 2 assert attacker_wins
def test_invalid_ship_die(self): with pytest.raises(ValueError, match="ship_die must be between 1 and 6!*"): a = Attacker(ship_die=7, combat_die_rolls=[1]) with pytest.raises(ValueError, match="ship_die must be between 1 and 6!*"): a = Attacker(ship_die=0, combat_die_rolls=[1])
def test_higher_attacker_loses(self): a = Attacker(ship_die=2, combat_die_rolls=[1]) d = Defender(ship_die=1, combat_die_rolls=[1]) attacker_wins = a.attack(d) assert a.total() == 3 assert d.total() == 2 assert not attacker_wins
def test_cruel(self): a = Attacker(ship_die=2, combat_die_rolls=[2], cards=["cruel"]) d = Defender(ship_die=1, combat_die_rolls=[2, 5]) assert a.cards == ("cruel", ) attacker_wins = a.attack(d) assert a.total() == 4 assert d.total() == 6 assert attacker_wins
def test_ferocious(self): a = Attacker(ship_die=1, combat_die_rolls=[1], cards=["ferocious"]) d = Defender(ship_die=1, combat_die_rolls=[1]) assert a.cards == ("ferocious", ) attacker_wins = a.attack(d) assert a.total() == 1 assert d.total() == 2 assert attacker_wins
def test_strategic(self): a = Attacker(ship_die=1, combat_die_rolls=[1], cards=["strategic"]) d = Defender(ship_die=1, combat_die_rolls=[1]) assert a.cards == ("strategic", ) attacker_wins = a.attack(d) assert a.total() == 0 assert d.total() == 2 assert attacker_wins
def test_invalid_combat_die(self): with pytest.raises( ValueError, match="All combat_die_rolls must be between 1 and 6!*"): a = Attacker(ship_die=6, combat_die_rolls=[7]) with pytest.raises( ValueError, match="All combat_die_rolls must be between 1 and 6!*"): a = Attacker(ship_die=6, combat_die_rolls=[0])
def test_stubborn_defender(self): a = Attacker(ship_die=2, combat_die_rolls=[1]) d = Defender(ship_die=2, combat_die_rolls=[1], cards=["stubborn"]) assert d.cards == ("stubborn", ) attacker_wins = a.attack(d) # Defender breaks ties when they hold Stubborn assert a.total() == 3 assert d.total() == 3 assert not attacker_wins
def test_stubborn_attacker(self): a = Attacker(ship_die=2, combat_die_rolls=[2], cards=["stubborn"]) d = Defender(ship_die=2, combat_die_rolls=[1]) assert a.cards == ("stubborn", ) attacker_wins = a.attack(d) assert a.total() == 4 assert d.total() == 3 # Stubborn does nothing when held by attacker assert not attacker_wins
def test_rational(self): a = Attacker(ship_die=2, combat_die_rolls=[1]) d = Defender(ship_die=1, combat_die_rolls=[3], cards=["rational"]) assert d.cards == ("rational", ) attacker_wins = a.attack(d) assert a.total() == 3 assert d.total() == 4 assert attacker_wins # Only one, because Scrappy doesn't do anything on defense! assert d.combat_die_rolls == [3]
def test_scrappy_attacker(self): a = Attacker( ship_die=2, combat_die_rolls=[4, 5], cards=["scrappy"], ) d = Defender(ship_die=1, combat_die_rolls=[2]) assert a.cards == ("scrappy", ) attacker_wins = a.attack(d) assert a.total() == 7 assert d.total() == 3 assert not attacker_wins
def test_relentless(self): a = Attacker( ship_die=2, combat_die_rolls=[4, 5], cards=["relentless"], ) d = Defender(ship_die=1, combat_die_rolls=[2]) assert a.cards == ("relentless", ) attacker_wins = a.attack(d) assert a.total() == 7 assert d.total() == 3 assert not attacker_wins
def do_fight(attacker_ship_die, defender_ship_die, attacker_cards, defender_cards): attacker = Attacker( ship_die=attacker_ship_die, # combat_die_rolls=[6], cards=attacker_cards, ) defender = Defender( ship_die=defender_ship_die, # combat_die_rolls=[1], cards=defender_cards, ) res = attacker.attack(defender) return res
def main(): args = parse_args() if args.verbose: init_logging(logging.DEBUG) else: init_logging(logging.INFO) if args.attacker_cards and args.defender_cards: shared = set(args.attacker_cards).intersection(set( args.defender_cards)) if shared: raise ValueError( f"Attacker and defender cannot have the same card! Shared cards: {shared}" ) res = qq( args.input, args.attacker_ship_die, args.defender_ship_die, tuple(args.attacker_cards) if args.attacker_cards else (), tuple(args.defender_cards) if args.defender_cards else (), ) attacker = Attacker(args.attacker_ship_die, args.attacker_cards) defender = Defender(args.defender_ship_die, args.defender_cards) if not args.trials or args.trials == 1: print(f"{attacker} vs. {defender}: {res:.2%}") else: print( f"{attacker} vs. {defender}: {res:.2%} " f"({prob_of_win(res, args.trials):.2%} over {args.trials} trials)")