Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import statistics
- class Weapon:
- def __init__(self, name: str, attacks: int, strength: int, armor_penetration: int, damage: int):
- self.name = name
- self.attacks = attacks
- self.strength = strength
- self.armor_penetration = armor_penetration
- self.damage = damage
- def __str__(self):
- return (f"Weapon: {self.name}, Attacks: {self.attacks}, Strength: {self.strength}, AP: {self.armor_penetration}, "
- f"Damage: {self.damage}")
- class Unit:
- def __init__(self, name: str, model_count: int, toughness: int, hit_skill: int, armor: int, weapon: Weapon, wounds: int):
- self.name = name
- self.model_count = model_count
- self.toughness = toughness
- self.hit_skill = hit_skill
- self.armor = armor
- self.weapon = weapon
- self.wounds = wounds
- self.total_wounds = model_count * wounds
- def attack(self, target):
- hits = 0
- wounds = 0
- failed_saves = 0
- # Roll to hit
- for _ in range(self.model_count * self.weapon.attacks):
- roll = random.randint(1, 6)
- if roll >= self.hit_skill:
- hits += 1
- # Roll to wound
- for _ in range(hits):
- roll = random.randint(1, 6)
- if self.weapon.strength >= 2 * target.toughness:
- wound_roll_needed = 2
- elif self.weapon.strength > target.toughness:
- wound_roll_needed = 3
- elif self.weapon.strength == target.toughness:
- wound_roll_needed = 4
- elif self.weapon.strength * 2 <= target.toughness:
- wound_roll_needed = 6
- else:
- wound_roll_needed = 5
- if roll >= wound_roll_needed:
- wounds += 1
- # Target rolls armor saves
- for _ in range(wounds):
- save_roll_needed = max(2, target.armor - self.weapon.armor_penetration)
- roll = random.randint(1, 6)
- if roll < save_roll_needed:
- failed_saves += 1
- # Apply damage
- total_damage = failed_saves * self.weapon.damage
- target.total_wounds -= total_damage
- target.model_count = max(0, target.total_wounds // target.wounds)
- def is_alive(self):
- return self.model_count > 0
- def combat_simulation(unit1, unit2):
- first_attacker = random.choice([unit1, unit2])
- second_attacker = unit2 if first_attacker == unit1 else unit1
- rounds = 0
- while unit1.is_alive() and unit2.is_alive():
- first_attacker.attack(second_attacker)
- if second_attacker.is_alive():
- second_attacker.attack(first_attacker)
- rounds += 1
- winner = unit1 if unit1.is_alive() else unit2
- first_attacker_won = (winner == first_attacker)
- return (winner == unit1, winner.total_wounds, rounds, first_attacker_won)
- simulation_count = 9999
- space_marine_model_count = 100
- guardsman_model_count = 400
- def run_simulations(n=simulation_count):
- results = []
- for i in range(n):
- guardsmen = Unit("Guardsmen", model_count=guardsman_model_count, toughness=3, hit_skill=4, armor=5, weapon=lasgun, wounds=1)
- space_marines = Unit("Space Marines", model_count=space_marine_model_count, toughness=4, hit_skill=3, armor=3, weapon=bolter, wounds=2)
- result = combat_simulation(guardsmen, space_marines)
- if result:
- results.append(result)
- if not results:
- print("Error: No results recorded. Check combat simulation logic.")
- return
- # Compute statistics
- guardsmen_wins = sum(1 for r in results if r[0])
- win_percentage = (guardsmen_wins / n) * 100
- guardsmen_wound_results = [r[1] for r in results if r[0]]
- space_marines_wound_results = [r[1] for r in results if not r[0]]
- round_results = [r[2] for r in results]
- first_attacker_wins = sum(1 for r in results if r[3])
- first_attacker_win_percentage = (first_attacker_wins / n) * 100
- if guardsmen_wound_results:
- guardsmen_median_wounds = statistics.median(guardsmen_wound_results)
- else:
- guardsmen_median_wounds = 0
- if space_marines_wound_results:
- space_marines_median_wounds = statistics.median(space_marines_wound_results)
- else:
- space_marines_median_wounds = 0
- median_rounds = statistics.median(round_results)
- space_percentage = space_marines_median_wounds / (2 * space_marine_model_count)
- guard_percentage = guardsmen_median_wounds / guardsman_model_count
- if win_percentage < 50:
- print(f"Space Marines won {100 - win_percentage:.2f}% of the time.")
- print(f"Median wounds remaining for the Space Marine winner: {space_marines_median_wounds} ({space_percentage:.2f})")
- else:
- print(f"Guardsmen won {win_percentage:.2f}% of the time.")
- print(f"Median wounds remaining for the Guardsmen winner: {guardsmen_median_wounds} ({guard_percentage:.2f})")
- print(f"There were a median of {median_rounds} rounds.")
- print(f"The first attacker won {first_attacker_win_percentage:.2f}% of the time.")
- # Example Usage
- lasgun = Weapon("Lasgun", attacks=1, strength=3, armor_penetration=0, damage=1)
- bolter = Weapon("Bolter", attacks=2, strength=4, armor_penetration=0, damage=1)
- run_simulations()
Advertisement
Add Comment
Please, Sign In to add comment