mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
Civil War (Python): Fix variable names
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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__":
|
||||
|
||||
Reference in New Issue
Block a user