diff --git a/25_Chief/python/chief.py b/25_Chief/python/chief.py index 720a0c88..d8af319b 100644 --- a/25_Chief/python/chief.py +++ b/25_Chief/python/chief.py @@ -29,19 +29,21 @@ def game() -> None: print("\nTake a Number and ADD 3. Now, Divide this number by 5 and") print("multiply by 8. Now, Divide by 5 and add the same. Subtract 1") - resp = float(input("\nWhat do you have? ")) - comp_guess = (((resp - 4) * 5) / 8) * 5 - 3 - resp2 = input(f"\nI bet your number was {comp_guess} was I right(Yes or No)? ") + you_have = float(input("\nWhat do you have? ")) + comp_guess = (((you_have - 4) * 5) / 8) * 5 - 3 + first_guess_right = input( + f"\nI bet your number was {comp_guess} was I right(Yes or No)? " + ) - if resp2.lower() == "yes": + if first_guess_right.lower() == "yes": print("\nHuh, I Knew I was unbeatable") print("And here is how i did it") print_solution(comp_guess) input() else: - resp3 = float(input("\nHUH!! what was you original number? ")) + original_number = float(input("\nHUH!! what was you original number? ")) - if resp3 == comp_guess: + if original_number == comp_guess: print("\nThat was my guess, AHA i was right") print( "Shamed to accept defeat i guess, don't worry you can master mathematics too" @@ -52,11 +54,11 @@ def game() -> None: else: print("\nSo you think you're so smart, EH?") print("Now, Watch") - print_solution(resp3) + print_solution(original_number) - resp4 = input("\nNow do you believe me? ") + believe_me = input("\nNow do you believe me? ") - if resp4.lower() == "yes": + if believe_me.lower() == "yes": print("\nOk, Lets play again sometime bye!!!!") input() else: diff --git a/27_Civil_War/python/Civilwar.py b/27_Civil_War/python/Civilwar.py index 7a0ca2e1..14b88e01 100644 --- a/27_Civil_War/python/Civilwar.py +++ b/27_Civil_War/python/Civilwar.py @@ -2,9 +2,94 @@ Original game design: Cram, Goodie, Hibbard Lexington H.S. Modifications: G. Paul, R. Hess (Ties), 1973 """ +import enum import math import random -from typing import List, Tuple +from dataclasses import dataclass +from typing import Dict, List, Literal, Tuple + + +class AttackState(enum.Enum): + DEFENSIVE = 1 + BOTH_OFFENSIVE = 2 + OFFENSIVE = 3 + + +CONF = 1 +UNION = 2 + + +@dataclass +class PlayerStat: + food: float = 0 + salaries: float = 0 + ammunition: float = 0 + + desertions: float = 0 + casualties: float = 0 + morale: float = 0 + strategy: int = 0 + available_men: int = 0 + available_money: int = 0 + + army_c: float = 0 + army_m: float = 0 # available_men ???? + inflation: float = 0 + + r: float = 0 + t: float = 0 # casualties + desertions + q: float = 0 # accumulated cost? + p: float = 0 + m: float = 0 + + is_player = False + excessive_losses = False + + def set_available_money(self): + if self.is_player: + factor = 1 + (self.r - self.q) / (self.r + 1) + else: + factor = 1 + self.available_money = 100 * math.floor( + (self.army_m * (100 - self.inflation) / 2000) * factor + 0.5 + ) + + def get_cost(self) -> float: + return self.food + self.salaries + self.ammunition + + def get_army_factor(self) -> float: + return 1 + (self.p - self.t) / (self.m + 1) + + def get_present_men(self) -> float: + return self.army_m * self.get_army_factor() + + +def simulate_losses(player1: PlayerStat, player2: PlayerStat) -> float: + """Simulate losses of player 1""" + tmp = (2 * player1.army_c / 5) * ( + 1 + 1 / (2 * (abs(player1.strategy - player2.strategy) + 1)) + ) + tmp = tmp * (1.28 + (5 * player1.army_m / 6) / (player1.ammunition + 1)) + tmp = math.floor(tmp * (1 + 1 / player1.morale) + 0.5) + return tmp + + +def update_army(player: PlayerStat, enemy: PlayerStat, use_factor=False) -> None: + player.casualties = simulate_losses(player, enemy) + player.desertions = 100 / player.morale + + loss = player.casualties + player.desertions + if not use_factor: + present_men: float = player.available_men + else: + present_men = player.get_present_men() + if loss >= present_men: + factor = player.get_army_factor() + if not use_factor: + factor = 1 + player.casualties = math.floor(13 * player.army_m / 20 * factor) + player.desertions = 7 * player.casualties / 13 + player.excessive_losses = True def get_choice(prompt: str, choices: List[str]) -> str: @@ -15,6 +100,14 @@ def get_choice(prompt: str, choices: List[str]) -> str: return choice +def get_morale(stat: PlayerStat, enemy: PlayerStat) -> float: + """Higher is better""" + enemy_strength = 5 * enemy.army_m / 6 + return (2 * math.pow(stat.food, 2) + math.pow(stat.salaries, 2)) / math.pow( + enemy_strength, 2 + ) + 1 + + def main() -> None: battles = [ [ @@ -74,38 +167,39 @@ def main() -> None: ], ] - historical_data: List[Tuple[str, float, float, float, int, int]] = [ - ("", 0, 0, 0, 0, 0), - ("BULL RUN", 18000, 18500, 1967, 2708, 1), - ("SHILOH", 40000.0, 44894.0, 10699, 13047, 3), - ("SEVEN DAYS", 95000.0, 115000.0, 20614, 15849, 3), - ("SECOND BULL RUN", 54000.0, 63000.0, 10000, 14000, 2), - ("ANTIETAM", 40000.0, 50000.0, 10000, 12000, 3), - ("FREDERICKSBURG", 75000.0, 120000.0, 5377, 12653, 1), - ("MURFREESBORO", 38000.0, 45000.0, 11000, 12000, 1), - ("CHANCELLORSVILLE", 32000, 90000.0, 13000, 17197, 2), - ("VICKSBURG", 50000.0, 70000.0, 12000, 19000, 1), - ("GETTYSBURG", 72500.0, 85000.0, 20000, 23000, 3), - ("CHICKAMAUGA", 66000.0, 60000.0, 18000, 16000, 2), - ("CHATTANOOGA", 37000.0, 60000.0, 36700.0, 5800, 2), - ("SPOTSYLVANIA", 62000.0, 110000.0, 17723, 18000, 2), - ("ATLANTA", 65000.0, 100000.0, 8500, 3700, 1), + historical_data: List[Tuple[str, float, float, float, int, AttackState]] = [ + ("", 0, 0, 0, 0, AttackState.DEFENSIVE), + ("BULL RUN", 18000, 18500, 1967, 2708, AttackState.DEFENSIVE), + ("SHILOH", 40000.0, 44894.0, 10699, 13047, AttackState.OFFENSIVE), + ("SEVEN DAYS", 95000.0, 115000.0, 20614, 15849, AttackState.OFFENSIVE), + ("SECOND BULL RUN", 54000.0, 63000.0, 10000, 14000, AttackState.BOTH_OFFENSIVE), + ("ANTIETAM", 40000.0, 50000.0, 10000, 12000, AttackState.OFFENSIVE), + ("FREDERICKSBURG", 75000.0, 120000.0, 5377, 12653, AttackState.DEFENSIVE), + ("MURFREESBORO", 38000.0, 45000.0, 11000, 12000, AttackState.DEFENSIVE), + ("CHANCELLORSVILLE", 32000, 90000.0, 13000, 17197, AttackState.BOTH_OFFENSIVE), + ("VICKSBURG", 50000.0, 70000.0, 12000, 19000, AttackState.DEFENSIVE), + ("GETTYSBURG", 72500.0, 85000.0, 20000, 23000, AttackState.OFFENSIVE), + ("CHICKAMAUGA", 66000.0, 60000.0, 18000, 16000, AttackState.BOTH_OFFENSIVE), + ("CHATTANOOGA", 37000.0, 60000.0, 36700.0, 5800, AttackState.BOTH_OFFENSIVE), + ("SPOTSYLVANIA", 62000.0, 110000.0, 17723, 18000, AttackState.BOTH_OFFENSIVE), + ("ATLANTA", 65000.0, 100000.0, 8500, 3700, AttackState.DEFENSIVE), ] - sa = {} - dollars_available = {} - food_array = {} - salaries = {} - ammunition = {} - oa = {} + confederate_strategy_prob_distribution = {} + + # What do you spend money on? + stats: Dict[int, PlayerStat] = { + CONF: PlayerStat(), + UNION: PlayerStat(), + } + print(" " * 26 + "CIVIL WAR") print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n") # Union info on likely confederate strategy - sa[1] = 25 - sa[2] = 25 - sa[3] = 25 - sa[4] = 25 - party = -1 # number of players in the game + confederate_strategy_prob_distribution[1] = 25 + confederate_strategy_prob_distribution[2] = 25 + confederate_strategy_prob_distribution[3] = 25 + confederate_strategy_prob_distribution[4] = 25 print() show_instructions = get_choice( "DO YOU WANT INSTRUCTIONS? YES OR NO -- ", ["YES", "NO"] @@ -142,10 +236,12 @@ def main() -> None: print() print() print("ARE THERE TWO GENERALS PRESENT ", end="") - bs = get_choice("(ANSWER YES OR NO) ", ["YES", "NO"]) - if bs == "YES": - party = 2 - elif bs == "NO": + two_generals = get_choice("(ANSWER YES OR NO) ", ["YES", "NO"]) == "YES" + stats[CONF].is_player = True + if two_generals: + party: Literal[1, 2] = 2 # number of players in the game + stats[UNION].is_player = True + else: party = 1 print() print("YOU ARE THE CONFEDERACY. GOOD LUCK!") @@ -162,282 +258,286 @@ def main() -> None: print("AFTER REQUESTING A BATTLE, DO YOU WISH ", end="") print("BATTLE DESCRIPTIONS ", end="") xs = get_choice("(ANSWER YES OR NO) ", ["YES", "NO"]) - line = 0 - w = 0 - r1: float = 0 - q1: float = 0 - m3: float = 0 - m4: float = 0 - p1: float = 0 - p2: float = 0 - t1: float = 0 - t2: float = 0 - for i in range(1, 3): - dollars_available[i] = 0 - food_array[i] = 0 - salaries[i] = 0 - ammunition[i] = 0 - oa[i] = 0 - r2: float = 0 - q2 = 0 - c6: float = 0 - food = 0 - w0 = 0 - strategy_index = 0 - union_strategy_index = 0 - u = 0 - u2 = 0 + confederacy_lost = 0 + confederacy_win = 0 + for i in [CONF, UNION]: + stats[i].p = 0 + stats[i].m = 0 + stats[i].t = 0 + stats[i].available_money = 0 + stats[i].food = 0 + stats[i].salaries = 0 + stats[i].ammunition = 0 + stats[i].strategy = 0 + stats[i].excessive_losses = False + confederacy_unresolved = 0 random_nb: float = 0 while True: print() print() print() - simulated_battle_index = int(input("WHICH BATTLE DO YOU WISH TO SIMULATE? ")) + simulated_battle_index = int( + get_choice( + "WHICH BATTLE DO YOU WISH TO SIMULATE? (0-14) ", + [str(i) for i in range(15)], + ) + ) if simulated_battle_index < 1 or simulated_battle_index > 14: break if simulated_battle_index != 0 or random_nb == 0: - cs = historical_data[simulated_battle_index][0] - m1 = historical_data[simulated_battle_index][1] - m2 = historical_data[simulated_battle_index][2] - c1 = historical_data[simulated_battle_index][3] - c2 = historical_data[simulated_battle_index][4] - m = historical_data[simulated_battle_index][5] - u = 0 + loaded_battle = historical_data[simulated_battle_index] + battle_name = loaded_battle[0] + stats[CONF].army_m = loaded_battle[1] + stats[UNION].army_m = loaded_battle[2] + stats[CONF].army_c = loaded_battle[3] + stats[UNION].army_c = loaded_battle[4] + stats[CONF].excessive_losses = False + # Inflation calc - i1 = 10 + (line - w) * 2 - i2 = 10 + (w - line) * 2 - # Money available - dollars_available[1] = 100 * math.floor( - (m1 * (100 - i1) / 2000) * (1 + (r1 - q1) / (r1 + 1)) + 0.5 - ) - dollars_available[2] = 100 * math.floor(m2 * (100 - i2) / 2000 + 0.5) - if bs == "YES": - dollars_available[2] = 100 * math.floor( - (m2 * (100 - i2) / 2000) * (1 + (r2 - q2) / (r2 + 1)) + 0.5 - ) - # Men available - m5 = math.floor(m1 * (1 + (p1 - t1) / (m3 + 1))) - m6 = math.floor(m2 * (1 + (p2 - t2) / (m4 + 1))) - f1 = 5 * m1 / 6 + stats[CONF].inflation = 10 + (confederacy_lost - confederacy_win) * 2 + stats[UNION].inflation = 10 + (confederacy_win - confederacy_lost) * 2 + + # Money and Men available + for i in [CONF, UNION]: + stats[i].set_available_money() + stats[i].available_men = math.floor(stats[i].get_army_factor()) print() print() print() print() print() - print(f"THIS IS THE BATTLE OF {cs}") + print(f"THIS IS THE BATTLE OF {battle_name}") if xs != "NO": print("\n".join(battles[simulated_battle_index - 1])) else: - print(cs + " INSTANT REPLAY") + print(f"{battle_name} INSTANT REPLAY") print() - print(" \tCONFEDERACY\t UNION") - print(f"MEN\t {m5}\t\t {m6}") - print(f"MONEY\t ${dollars_available[1]}\t\t${dollars_available[2]}") - print(f"INFLATION\t {i1 + 15}%\t {i2}%") + print(" CONFEDERACY\t UNION") + print(f"MEN {stats[CONF].available_men}\t\t {stats[UNION].available_men}") + print( + f"MONEY ${stats[CONF].available_money}\t${stats[UNION].available_money}" + ) + print(f"INFLATION {stats[CONF].inflation + 15}%\t\t {stats[UNION].inflation}%") print() # ONLY IN PRINTOUT IS CONFED INFLATION = I1 + 15 % # IF TWO GENERALS, INPUT CONFED, FIRST - for i in range(1, party + 1): - if bs == "YES" and i == 1: + for player_index in range(1, party + 1): + if two_generals and player_index == 1: print("CONFEDERATE GENERAL---", end="") print("HOW MUCH DO YOU WISH TO SPEND FOR") while True: - food = int(input(" - FOOD...... ? ")) - if food < 0: - if r1 == 0: + food_input = int(input(" - FOOD...... ? ")) + if food_input < 0: + if stats[CONF].r == 0: print("NO PREVIOUS ENTRIES") continue print("ASSUME YOU WANT TO KEEP SAME ALLOCATIONS") print() break - food_array[i] = food + stats[player_index].food = food_input while True: - salaries[i] = int(input(" - SALARIES.. ? ")) - if salaries[i] >= 0: + stats[player_index].salaries = int(input(" - SALARIES.. ? ")) + if stats[player_index].salaries >= 0: break print("NEGATIVE VALUES NOT ALLOWED.") while True: - ammunition[i] = int(input(" - AMMUNITION ? ")) - if ammunition[i] >= 0: + stats[player_index].ammunition = int(input(" - AMMUNITION ? ")) + if stats[player_index].ammunition >= 0: break print("NEGATIVE VALUES NOT ALLOWED.") print() - if food_array[i] + salaries[i] + ammunition[i] > dollars_available[i]: - print(f"THINK AGAIN! YOU HAVE ONLY ${dollars_available[i]}") + if stats[player_index].get_cost() > stats[player_index].available_money: + print( + f"THINK AGAIN! YOU HAVE ONLY ${stats[player_index].available_money}" + ) else: break - if bs != "YES" or i == 2: + if not two_generals or player_index == 2: break print("UNION GENERAL---", end="") - for z in range(1, party + 1): - if bs == "YES": - if z == 1: + for player_index in range(1, party + 1): + if two_generals: + if player_index == 1: print("CONFEDERATE ", end="") else: print(" UNION ", end="") - # Find morale - o = (2 * math.pow(food_array[z], 2) + math.pow(salaries[z], 2)) / math.pow( - f1, 2 - ) + 1 - if o >= 10: + morale = get_morale(stats[player_index], stats[1 + player_index % 2]) + + if morale >= 10: print("MORALE IS HIGH") - elif o >= 5: + elif morale >= 5: print("MORALE IS FAIR") else: print("MORALE IS POOR") - if bs != "YES": + if not two_generals: break - oa[z] = o # type: ignore + stats[player_index].morale = morale # type: ignore - o2 = oa[2] - o = oa[1] + stats[UNION].morale = get_morale(stats[UNION], stats[CONF]) + stats[CONF].morale = get_morale(stats[CONF], stats[UNION]) print("CONFEDERATE GENERAL---") # Actual off/def battle situation - if m == 3: + if loaded_battle[5] == AttackState.OFFENSIVE: print("YOU ARE ON THE OFFENSIVE") - elif m == 1: + elif loaded_battle[5] == AttackState.DEFENSIVE: print("YOU ARE ON THE DEFENSIVE") else: print("BOTH SIDES ARE ON THE OFFENSIVE") print() # Choose strategies - if bs != "YES": + if not two_generals: while True: - strategy_index = int(input("YOUR STRATEGY ")) - if abs(strategy_index - 3) < 3: + stats[CONF].strategy = int(input("YOUR STRATEGY ")) + if abs(stats[CONF].strategy - 3) < 3: break - print(f"STRATEGY {strategy_index} NOT ALLOWED.") - if strategy_index == 5: + print(f"STRATEGY {stats[CONF].strategy} NOT ALLOWED.") + if stats[CONF].strategy == 5: print("THE CONFEDERACY HAS SURRENDERED.") break # Union strategy is computer chosen if simulated_battle_index == 0: while True: - union_strategy_index = int(input("UNION STRATEGY IS ")) - if union_strategy_index > 0 and union_strategy_index < 5: + stats[UNION].strategy = int(input("UNION STRATEGY IS ")) + if stats[UNION].strategy > 0 and stats[UNION].strategy < 5: break print("ENTER 1, 2, 3, OR 4 (USUALLY PREVIOUS UNION STRATEGY)") else: s0 = 0 random_nb = random.random() * 100 - for i in range(1, 5): - s0 += sa[i] + for player_index in range(1, 5): + s0 += confederate_strategy_prob_distribution[player_index] # If actual strategy info is in program data statements # then r-100 is extra weight given to that strategy. if random_nb < s0: break - union_strategy_index = i - print(union_strategy_index) + stats[UNION].strategy = player_index + print(stats[UNION].strategy) else: - for i in range(1, 3): - if i == 1: + for player_index in [1, 2]: + if player_index == 1: print("CONFEDERATE STRATEGY ? ", end="") while True: - strategy_index = int(input()) - if abs(strategy_index - 3) < 3: + stats[CONF].strategy = int(input()) + if abs(stats[CONF].strategy - 3) < 3: break - print(f"STRATEGY {strategy_index} NOT ALLOWED.") + print(f"STRATEGY {stats[CONF].strategy} NOT ALLOWED.") print("YOUR STRATEGY ? ", end="") - if i == 2: - union_strategy_index = strategy_index - strategy_index = previous_strategy # type: ignore # noqa: F821 - if union_strategy_index != 5: + if player_index == 2: + stats[UNION].strategy = stats[CONF].strategy + stats[CONF].strategy = previous_strategy # type: ignore # noqa: F821 + if stats[UNION].strategy != 5: break else: - previous_strategy = strategy_index # noqa: F841 + previous_strategy = stats[CONF].strategy # noqa: F841 print("UNION STRATEGY ? ", end="") - # Simulated losses - North - c6 = (2 * c2 / 5) * ( - 1 + 1 / (2 * (abs(union_strategy_index - strategy_index) + 1)) - ) - c6 = c6 * (1.28 + (5 * m2 / 6) / (ammunition[2] + 1)) - c6 = math.floor(c6 * (1 + 1 / o2) + 0.5) - # If loss > men present, rescale losses - e2 = 100 / o2 - if math.floor(c6 + e2) >= m6: - c6 = math.floor(13 * m6 / 20) - e2 = 7 * c6 / 13 - u2 = 1 + + update_army(stats[UNION], stats[CONF], use_factor=False) + # Calculate simulated losses print() print() print() print("\t\tCONFEDERACY\tUNION") - c5 = (2 * c1 / 5) * ( - 1 + 1 / (2 * (abs(union_strategy_index - strategy_index) + 1)) - ) - c5 = math.floor(c5 * (1 + 1 / o) * (1.28 + f1 / (ammunition[1] + 1)) + 0.5) - e = 100 / o - if c5 + 100 / o >= m1 * (1 + (p1 - t1) / (m3 + 1)): - c5 = math.floor(13 * m1 / 20 * (1 + (p1 - t1) / (m3 + 1))) - e = 7 * c5 / 13 - u = 1 + update_army(stats[CONF], stats[UNION], use_factor=True) if party == 1: - c6 = math.floor(17 * c2 * c1 / (c5 * 20)) - e2 = 5 * o + stats[UNION].casualties = math.floor( + 17 + * stats[UNION].army_c + * stats[CONF].army_c + / (stats[CONF].casualties * 20) + ) + stats[CONF].desertions = 5 * morale - print("CASUALTIES\t" + str(c5) + "\t\t" + str(c6)) - print("DESERTIONS\t" + str(math.floor(e)) + "\t\t" + str(math.floor(e2))) + print( + "CASUALTIES\t" + + str(stats[CONF].casualties) + + "\t\t" + + str(stats[UNION].casualties) + ) + print( + "DESERTIONS\t" + + str(math.floor(stats[CONF].desertions)) + + "\t\t" + + str(math.floor(stats[UNION].desertions)) + ) print() - if bs == "YES": - print("COMPARED TO THE ACTUAL CASUALTIES AT " + str(cs)) + if two_generals: + print("COMPARED TO THE ACTUAL CASUALTIES AT " + str(battle_name)) print( "CONFEDERATE: " - + str(math.floor(100 * (c5 / c1) + 0.5)) + + str( + math.floor( + 100 * (stats[CONF].casualties / stats[CONF].army_c) + 0.5 + ) + ) + "% OF THE ORIGINAL" ) print( "UNION: " - + str(math.floor(100 * (c6 / c2) + 0.5)) + + str( + math.floor( + 100 * (stats[UNION].casualties / stats[UNION].army_c) + 0.5 + ) + ) + "% OF THE ORIGINAL" ) print() # Find who won - if u == 1 and u2 == 1 or (u != 1 and u2 != 1 and c5 + e == c6 + e2): + if ( + stats[CONF].excessive_losses + and stats[UNION].excessive_losses + or ( + not stats[CONF].excessive_losses + and not stats[UNION].excessive_losses + and stats[CONF].casualties + stats[CONF].desertions + == stats[UNION].casualties + stats[CONF].desertions + ) + ): print("BATTLE OUTCOME UNRESOLVED") - w0 += 1 - elif u == 1 or (u != 1 and u2 != 1 and c5 + e > c6 + e2): - print("THE UNION WINS " + str(cs)) + confederacy_unresolved += 1 + elif stats[CONF].excessive_losses or ( + not stats[CONF].excessive_losses + and not stats[UNION].excessive_losses + and stats[CONF].casualties + stats[CONF].desertions + > stats[UNION].casualties + stats[CONF].desertions + ): + print(f"THE UNION WINS {battle_name}") if simulated_battle_index != 0: - line += 1 + confederacy_lost += 1 else: - print("THE CONFEDERACY WINS " + str(cs)) + print(f"THE CONFEDERACY WINS {battle_name}") if simulated_battle_index != 0: - w += 1 + confederacy_win += 1 # Lines 2530 to 2590 from original are unreachable. if simulated_battle_index != 0: - t1 += c5 + e - t2 += c6 + e2 - p1 += c1 - p2 += c2 - q1 += food_array[1] + salaries[1] + ammunition[1] - q2 += food_array[2] + salaries[2] + ammunition[2] - r1 += m1 * (100 - i1) / 20 - r2 += m2 * (100 - i2) / 20 - m3 += m1 - m4 += m2 + for i in [CONF, UNION]: + stats[i].t += stats[i].casualties + stats[i].desertions + stats[i].p += stats[i].army_c + stats[i].q += stats[i].get_cost() + stats[i].r += stats[i].army_m * (100 - stats[i].inflation) / 20 + stats[i].m += stats[i].army_m # Learn present strategy, start forgetting old ones - # present startegy of south gains 3*s, others lose s + # present strategy of south gains 3*s, others lose s # probability points, unless a strategy falls below 5 % . s = 3 s0 = 0 - for i in range(1, 5): - if sa[i] <= 5: + for player_index in range(1, 5): + if confederate_strategy_prob_distribution[player_index] <= 5: continue - sa[i] -= 5 + confederate_strategy_prob_distribution[player_index] -= 5 s0 += s - sa[strategy_index] += s0 + confederate_strategy_prob_distribution[stats[CONF].strategy] += s0 - u = 0 - u2 = 0 + stats[CONF].excessive_losses = False + stats[UNION].excessive_losses = False print("---------------") continue @@ -447,27 +547,39 @@ def main() -> None: print() print() print() - print(f"THE CONFEDERACY HAS WON {w} BATTLES AND LOST {line}") - if strategy_index == 5 or (union_strategy_index != 5 and w <= line): + print( + f"THE CONFEDERACY HAS WON {confederacy_win} BATTLES AND LOST {confederacy_lost}" + ) + if stats[CONF].strategy == 5 or ( + stats[UNION].strategy != 5 and confederacy_win <= confederacy_lost + ): print("THE UNION HAS WON THE WAR") else: print("THE CONFEDERACY HAS WON THE WAR") print() - if r1 > 0: - print(f"FOR THE {w + line + w0} BATTLES FOUGHT (EXCLUDING RERUNS)") + if stats[CONF].r > 0: + print( + f"FOR THE {confederacy_win + confederacy_lost + confederacy_unresolved} BATTLES FOUGHT (EXCLUDING RERUNS)" + ) print(" \t \t ") print("CONFEDERACY\t UNION") - print(f"HISTORICAL LOSSES\t{math.floor(p1 + 0.5)}\t{math.floor(p2 + 0.5)}") - print(f"SIMULATED LOSSES\t{math.floor(t1 + 0.5)}\t{math.floor(t2 + 0.5)}") + print( + f"HISTORICAL LOSSES\t{math.floor(stats[CONF].p + 0.5)}\t{math.floor(stats[UNION].p + 0.5)}" + ) + print( + f"SIMULATED LOSSES\t{math.floor(stats[CONF].t + 0.5)}\t{math.floor(stats[UNION].t + 0.5)}" + ) print() print( - f" % OF ORIGINAL\t{math.floor(100 * (t1 / p1) + 0.5)}\t{math.floor(100 * (t2 / p2) + 0.5)}" + f" % OF ORIGINAL\t{math.floor(100 * (stats[CONF].t / stats[CONF].p) + 0.5)}\t{math.floor(100 * (stats[UNION].t / stats[UNION].p) + 0.5)}" ) - if bs != "YES": + if not two_generals: print() print("UNION INTELLIGENCE SUGGEST THAT THE SOUTH USED") print("STRATEGIES 1, 2, 3, 4 IN THE FOLLOWING PERCENTAGES") - print(f"{sa[1]} {sa[2]} {sa[3]} {sa[4]}") + print( + f"{confederate_strategy_prob_distribution[CONF]} {confederate_strategy_prob_distribution[UNION]} {confederate_strategy_prob_distribution[3]} {confederate_strategy_prob_distribution[4]}" + ) if __name__ == "__main__":