Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import sys
- import time
- from colorama import Fore, Style, init
- # Initialize colorama with automatic reset and stripping for unsupported environments
- init(autoreset=True, strip=True)
- # ASCII Art Title
- TITLE = f"""
- {Fore.CYAN} __ __ _ ____ _ _______ _____
- | \/ | / \ | _ \| |/ / ____|_ _|
- | |\/| | / _ \ | |_) | ' /| _| | |
- | | | |/ ___ \| _ <| . \| |___ | |
- |_| |_/_/ \_\_| \_\_|\_\_____| |_|
- {Style.RESET_ALL}
- """
- # Welcome Text without the '=' lines, with yellow coloring
- WELCOME_TEXT = f"""{Fore.YELLOW}Welcome to the Text-Based Trading Game!
- Your goal is to accumulate as much wealth as possible within a set number of turns.
- Explore a variety of goods, manage your cargo capacity, and navigate the dynamic market.
- Be mindful of your relationships with towns—they play a crucial role in your success.{Style.RESET_ALL}"""
- # HELP Text with detailed rules and trading categories
- HELP_TEXT = f"""
- {Fore.GREEN}Game Rules and Instructions:{Style.RESET_ALL}
- 1. {Fore.YELLOW}Objective:{Style.RESET_ALL}
- Accumulate as much wealth as possible within the allotted number of turns.
- 2. {Fore.YELLOW}Commands:{Style.RESET_ALL}
- - {Fore.CYAN}BUY:{Style.RESET_ALL} Purchase goods from the market.
- - {Fore.CYAN}SELL:{Style.RESET_ALL} Sell goods from your inventory.
- - {Fore.CYAN}TRAVEL:{Style.RESET_ALL} Move to a different town.
- - {Fore.CYAN}STATUS:{Style.RESET_ALL} View your current status, inventory, and relationships.
- - {Fore.CYAN}UPGRADE:{Style.RESET_ALL} Upgrade your cargo capacity.
- - {Fore.CYAN}NETWORK:{Style.RESET_ALL} Get rumors and information about other towns.
- - {Fore.CYAN}HELP:{Style.RESET_ALL} View the game rules and trading categories.
- - {Fore.CYAN}EXIT:{Style.RESET_ALL} Exit the game.
- 3. {Fore.YELLOW}Goods Categories and Their Impact on Relationships:{Style.RESET_ALL}
- - {Fore.CYAN}Strategic Goods:{Style.RESET_ALL} Gold, Gems, Iron
- - Buying or selling affects {Fore.CYAN}Trade Relations{Style.RESET_ALL}.
- - {Fore.CYAN}Supportive Goods:{Style.RESET_ALL} Food, Herbs, Cloth, Tea
- - Buying or selling improves {Fore.CYAN}Reputation{Style.RESET_ALL}.
- - {Fore.CYAN}Luxury Goods:{Style.RESET_ALL} Silk, Wine, Spices
- - Buying or selling influences {Fore.CYAN}Favor{Style.RESET_ALL}.
- 4. {Fore.YELLOW}Trading Tips:{Style.RESET_ALL}
- - All trading actions significantly impact relationships.
- - Relationships affect prices and trading conditions.
- - Events can drastically alter your relationships.
- 5. {Fore.YELLOW}Relationships with Towns:{Style.RESET_ALL}
- - {Fore.CYAN}Trade:{Style.RESET_ALL} Reflects your trading history with the town.
- - {Fore.CYAN}Reputation:{Style.RESET_ALL} Represents your overall standing and trustworthiness.
- - {Fore.CYAN}Favor:{Style.RESET_ALL} Indicates personal favor and goodwill from the town.
- 6. {Fore.YELLOW}Events:{Style.RESET_ALL}
- - Random events may occur, impacting markets and relationships.
- - Your global reputation can influence the likelihood of events.
- 7. {Fore.YELLOW}Turn Mechanics:{Style.RESET_ALL}
- - Actions like {Fore.CYAN}BUY, SELL, TRAVEL,{Style.RESET_ALL} and {Fore.CYAN}UPGRADE{Style.RESET_ALL} consume a turn.
- - Viewing {Fore.CYAN}STATUS, NETWORK,{Style.RESET_ALL} or {Fore.CYAN}HELP{Style.RESET_ALL} does not consume a turn.
- - {Fore.CYAN}Note:{Style.RESET_ALL} You can only use {Fore.CYAN}NETWORK{Style.RESET_ALL} once per turn.
- {Style.RESET_ALL}
- """
- # Goods and their base prices, weights, base supply, and base demand
- GOODS = {
- "Spices": {"base_price": 100, "weight": 5, "base_supply": 300, "base_demand": 300},
- "Gems": {"base_price": 500, "weight": 10, "base_supply": 150, "base_demand": 200},
- "Food": {"base_price": 50, "weight": 3, "base_supply": 400, "base_demand": 400},
- "Silk": {"base_price": 200, "weight": 4, "base_supply": 150, "base_demand": 200},
- "Iron": {"base_price": 150, "weight": 15, "base_supply": 200, "base_demand": 250},
- "Wine": {"base_price": 120, "weight": 6, "base_supply": 200, "base_demand": 250},
- "Tea": {"base_price": 80, "weight": 2, "base_supply": 300, "base_demand": 300},
- "Herbs": {"base_price": 60, "weight": 3, "base_supply": 350, "base_demand": 300},
- "Cloth": {"base_price": 180, "weight": 8, "base_supply": 100, "base_demand": 150},
- "Gold": {"base_price": 1000, "weight": 25, "base_supply": 80, "base_demand": 100},
- }
- # Goods categories for relationship impact
- SUPPORTIVE_GOODS = ["Food", "Herbs", "Cloth", "Tea"]
- STRATEGIC_GOODS = ["Gold", "Gems", "Iron"]
- LUXURY_GOODS = ["Silk", "Wine", "Spices"]
- # Combined list of all goods for inventory and selection
- ALL_GOODS = GOODS.copy()
- # Expanded list of Towns
- TOWNS = [
- "Onyxville", "Brightstone", "Crimsonburg", "Dusktown",
- "Sunset City", "Northport", "Riverside", "Hilltop",
- "Lakeside", "Oakwood", "Stormhaven", "Fairview"
- ]
- # List of possible random events
- GLOBAL_EVENTS = [
- # Existing negative global events
- "Global trade embargo reducing supply worldwide.",
- "Pandemic affecting demand for certain goods globally.",
- "Global inflation increasing prices across the board.",
- "Global recession decreasing purchasing power.",
- # Positive global events
- "A global trade agreement has been signed, reducing tariffs.",
- "Technological advancements have improved trade efficiency worldwide.",
- "A global festival increases demand for luxury goods.",
- ]
- LOCAL_EVENTS = [
- # Existing negative local events
- "Thieves attacked your caravan and stole some goods!",
- "A storm ruined your goods during travel.",
- "Disease outbreak decreased the demand for food.",
- "Pirates disrupted trade in the seas.",
- "Government imposed a tax on trade.",
- "Locusts devastated the food supplies in Dusktown.",
- "Bandit attack in Oakwood stole some of your goods.",
- "Natural disaster in Dusktown affecting multiple goods.",
- # Positive local events
- "You found a hidden stash of goods in the market!",
- "A wealthy patron gifts you valuable items!",
- "Your reputation has earned you a local tax exemption!",
- "A local festival boosts demand and prices for certain goods.",
- "Favorable winds reduce travel times temporarily.",
- "Merchants admire your honesty, improving relationships.",
- "An influential guild offers you a partnership.",
- "An overstock in the market reduces prices for certain goods.",
- "Local artisans gift you exquisite items to trade.",
- "Successful mediation improves trade relations between towns.",
- ]
- # Player relationships with towns
- RELATIONSHIP_BASE = 0 # Neutral
- RELATIONSHIP_MAX = 100
- RELATIONSHIP_MIN = -100
- # Difficulty settings
- DIFFICULTIES = {
- "EASY": {
- "event_chance": 0.12,
- "ai_aggressiveness": 0.7,
- "starting_money": 4000,
- "starting_cargo": 300,
- "turns": 60
- },
- "MEDIUM": {
- "event_chance": 0.2,
- "ai_aggressiveness": 1.0,
- "starting_money": 2500,
- "starting_cargo": 250,
- "turns": 55
- },
- "HARD": {
- "event_chance": 0.3,
- "ai_aggressiveness": 1.5,
- "starting_money": 1800,
- "starting_cargo": 200,
- "turns": 50
- }
- }
- class AITrader:
- """Represents an AI trader that interacts with the market each turn."""
- def __init__(self, trader_id, aggressiveness=1.0):
- self.trader_id = trader_id
- self.name = f"Trader_{trader_id}"
- self.aggressiveness = aggressiveness # Determines transaction sizes and frequency
- def perform_action(self, market):
- """AI trader performs buy or sell actions based on strategy."""
- # Determine number of actions based on aggressiveness
- num_actions = random.randint(1, 3) if self.aggressiveness > 1.0 else random.randint(1, 2)
- for _ in range(num_actions):
- # Decide action based on aggressiveness
- action = random.choices(["BUY", "SELL"], weights=[self.aggressiveness, 1.0])[0]
- # Choose a good to buy or sell
- goods_choices = list(ALL_GOODS.keys())
- goods_prob = []
- total_goods = len(goods_choices)
- for good in goods_choices:
- if good == "Gold":
- # Further reduce the probability for Gold
- goods_prob.append(0.05) # Very low probability
- elif good == "Gems":
- # Slightly reduce the probability for Gems
- goods_prob.append(0.1)
- else:
- # Distribute the remaining probability among other goods
- goods_prob.append(1.0) # Assign higher weight to other goods
- # Normalize the weights
- total_weight = sum(goods_prob)
- normalized_weights = [w / total_weight for w in goods_prob]
- good = random.choices(goods_choices, weights=normalized_weights, k=1)[0]
- # Determine quantity based on aggressiveness
- quantity = random.randint(1, max(1, int(10 * self.aggressiveness))) # Reduced max quantity
- if action == "BUY":
- # AI trader buys goods: decrease supply, increase demand
- if market.supply.get(good, 0) >= quantity:
- market.supply[good] -= quantity
- market.demand[good] += quantity * 0.5 # Reduced impact
- elif action == "SELL":
- # AI trader sells goods: increase supply, decrease demand
- market.supply[good] = market.supply.get(good, 0) + quantity
- market.demand[good] = market.demand.get(good, 0) - quantity * 0.5 # Reduced impact
- if market.demand.get(good, 0) < 50: # Prevent demand from going too low
- market.demand[good] = 50
- class Player:
- def __init__(self, starting_money, starting_cargo, game):
- self.starting_money = starting_money
- self.money = starting_money
- self.inventory = {good: 0 for good in GOODS}
- self.location = random.choice(TOWNS)
- self.turns = 0
- self.max_cargo = starting_cargo
- self.current_cargo = 0
- self.cargo_upgrades = 0
- self.relationships = {town: {
- "Trade": RELATIONSHIP_BASE,
- "Reputation": RELATIONSHIP_BASE,
- "Favor": RELATIONSHIP_BASE
- } for town in TOWNS}
- self.event_log = []
- self.visited_towns = set()
- self.visited_towns.add(self.location) # Add this line to include the starting town
- self.reputation = 0
- self.game = game # Reference to the game instance
- def modify_relationship(self, town, aspect, amount):
- multiplier = self.game.relation_multiplier
- adjusted_amount = int(amount * multiplier)
- new_score = self.relationships[town][aspect] + adjusted_amount
- new_score = int(max(RELATIONSHIP_MIN, min(new_score, RELATIONSHIP_MAX)))
- change = new_score - self.relationships[town][aspect]
- self.relationships[town][aspect] = new_score
- # Notify the player about the change
- if change > 0:
- slow_print(f"\n[{town} - {aspect}] Improved by {change} points!")
- elif change < 0:
- slow_print(f"\n[{town} - {aspect}] Worsened by {-change} points!")
- def get_overall_relationship_status(self, town):
- """Determines the overall relationship status based on individual aspects."""
- aspects = self.relationships[town]
- # Calculate average of all aspects
- average = sum(aspects.values()) / len(aspects)
- return get_relationship_status(average)
- def status(self):
- """Displays the player's current status with detailed relationship aspects."""
- slow_print(f"\n{Fore.GREEN}Player Status:{Style.RESET_ALL}")
- fast_print(f"Location: {self.location}")
- fast_print(f"Money: ${self.money}")
- fast_print(f"Cargo: {self.current_cargo}/{self.max_cargo} cargo space used")
- fast_print("Inventory:")
- for good, qty in self.inventory.items():
- if qty > 0:
- fast_print(f" {good}: {qty}")
- # Display visited towns
- fast_print("\nVisited Towns:")
- for town in sorted(self.visited_towns): # Sort for readability
- fast_print(f" - {town}")
- # Display relationships with detailed aspects
- fast_print("\nRelationships:")
- for town, aspects in self.relationships.items():
- overall_status = self.get_overall_relationship_status(town)
- relationship_info = ', '.join([
- f"{Fore.CYAN}{aspect}: {score}{Style.RESET_ALL}" for aspect, score in aspects.items()
- ])
- if overall_status in ["Ally", "Friendly"]:
- status_color = Fore.GREEN
- elif overall_status in ["Hostile", "Enemy"]:
- status_color = Fore.RED
- else:
- status_color = Fore.YELLOW
- fast_print(f" {town}: {relationship_info} | Overall: {status_color}{overall_status}{Style.RESET_ALL}")
- print()
- def status_short(self):
- """Displays the player's current status without relationship aspects."""
- slow_print(f"\n{Fore.GREEN}Player Status:{Style.RESET_ALL}")
- fast_print(f"Location: {self.location}")
- fast_print(f"Money: ${self.money}")
- fast_print(f"Cargo: {self.current_cargo}/{self.max_cargo} units used")
- fast_print("Inventory:")
- for good, qty in self.inventory.items():
- if qty > 0:
- fast_print(f" {good}: {qty}")
- print()
- def add_cargo(self, good, quantity):
- """Attempts to add cargo to the player's inventory."""
- # Determine weight based on whether the good is regular
- if good in GOODS:
- weight = GOODS[good]["weight"]
- else:
- weight = 5 # Default weight
- total_weight = weight * quantity
- if self.current_cargo + total_weight > self.max_cargo:
- return False, total_weight
- self.current_cargo += total_weight
- if good not in self.inventory:
- self.inventory[good] = 0
- self.inventory[good] += quantity
- return True, total_weight
- def remove_cargo(self, good, quantity):
- """Removes cargo from the player's inventory."""
- if good not in self.inventory:
- return
- # Determine weight based on whether the good is regular
- if good in GOODS:
- weight = GOODS[good]["weight"]
- else:
- weight = 5 # Default weight
- total_weight = weight * quantity
- self.inventory[good] -= quantity
- self.current_cargo -= total_weight
- if self.inventory[good] < 0:
- self.inventory[good] = 0
- if self.current_cargo < 0:
- self.current_cargo = 0
- def upgrade_cargo(self):
- """Allows the player to upgrade cargo capacity with a fixed cost of $500 per upgrade."""
- upgrade_cost = 500 # Fixed cost for each upgrade
- upgrade_amount = 50 # Fixed cargo increase per upgrade
- if self.money < upgrade_cost:
- slow_print("Insufficient funds to upgrade cargo capacity.")
- return False # Indicate that no upgrade was made
- confirm = input(f"Upgrade cargo capacity by {upgrade_amount} for ${upgrade_cost}? (Y/N): ").strip().upper()
- if confirm == 'Y':
- self.money -= upgrade_cost
- self.max_cargo += upgrade_amount
- self.cargo_upgrades += 1 # Increment the number of upgrades for tracking purposes
- slow_print(f"Cargo capacity increased by {upgrade_amount}. New capacity: {self.max_cargo}")
- self.event_log.append(f"Upgraded cargo capacity by {upgrade_amount} for ${upgrade_cost}.")
- return True # Indicate that upgrade was successful
- elif confirm == 'N':
- slow_print("Upgrade canceled.")
- return False # Indicate that no upgrade was made
- else:
- slow_print("ERROR: Invalid Input")
- return False # Indicate that no upgrade was made
- class Market:
- """Represents the market of a specific town."""
- PRICE_FLOOR = 10
- PRICE_CEILING = 2000
- def __init__(self, town, player):
- self.town = town
- self.player = player
- # Initialize supply and demand per good with increased random variations
- self.supply = {}
- self.demand = {}
- for good, info in GOODS.items():
- supply_variation = random.uniform(0.6, 1.4) # Increased range from 0.6-1.4
- demand_variation = random.uniform(0.6, 1.4) # Increased range from 0.6-1.4
- self.supply[good] = info["base_supply"] * supply_variation
- self.demand[good] = info["base_demand"] * demand_variation
- self.prices = {}
- self.generate_prices()
- # Initialize AI traders for the town
- self.ai_traders = [AITrader(trader_id=i+1, aggressiveness=random.uniform(0.7, 1.5)) for i in range(10)] # 10 AI traders per town
- def generate_prices(self):
- """Calculates current prices based on supply, demand, and relationship with the player."""
- relation_modifier = self.get_relationship_modifier(self.town)
- for good, info in GOODS.items():
- # Calculate price based on demand and supply with increased elasticity
- if self.supply.get(good, 0) == 0:
- price_multiplier = 2 # High price if no supply
- else:
- ratio = self.demand.get(good, 0) / self.supply.get(good, 0)
- elasticity = random.uniform(0.7, 1.3) # Adjusted elasticity range
- price_multiplier = ratio * elasticity
- new_price = int(GOODS[good]["base_price"] * price_multiplier * relation_modifier)
- new_price = max(self.PRICE_FLOOR, min(new_price, self.PRICE_CEILING))
- self.prices[good] = new_price
- def get_relationship_modifier(self, town):
- """Determines price modifiers based on multiple relationship aspects."""
- aspects = self.player.relationships[town]
- trade = aspects["Trade"]
- reputation = aspects["Reputation"]
- favor = aspects["Favor"]
- # Calculate individual modifiers
- if trade >= 80:
- trade_modifier = 0.60 # Increased discount: 40% discount
- elif trade >= 50:
- trade_modifier = 0.80 # 20% discount
- elif trade >= -20:
- trade_modifier = 1.00 # Neutral
- elif trade >= -60:
- trade_modifier = 1.25 # 25% price increase
- else:
- trade_modifier = 1.50 # 50% price increase
- if reputation >= 70:
- reputation_modifier = 0.85 # 15% discount
- elif reputation >= 40:
- reputation_modifier = 0.90 # 10% discount
- else:
- reputation_modifier = 1.00 # Neutral
- if favor >= 60:
- favor_modifier = 0.90 # 10% discount
- else:
- favor_modifier = 1.00 # Neutral
- # Combine modifiers by averaging
- overall_modifier = (trade_modifier + reputation_modifier + favor_modifier) / 3
- return overall_modifier
- def display_prices(self):
- """Displays the current prices, supply, demand, and weight for all goods in the market,
- along with the player's relationship status with the current town."""
- slow_print(f"\n{Fore.GREEN}Market Overview in {self.town}:{Style.RESET_ALL}")
- for good, price in self.prices.items():
- supply = int(self.supply.get(good, 0))
- demand = int(self.demand.get(good, 0))
- weight = GOODS[good]["weight"]
- available_cargo_space = self.player.max_cargo - self.player.current_cargo
- max_fit = available_cargo_space // weight if weight > 0 else "N/A"
- # Determine color based on price comparison
- base_price = GOODS[good]["base_price"]
- price_ratio = price / base_price
- if price_ratio < 0.8:
- # Good buy
- price_color = Fore.GREEN
- good_color = Fore.GREEN
- price_indicator = ""
- elif price_ratio > 1.2:
- # Bad buy
- price_color = Fore.RED
- good_color = Fore.RED
- price_indicator = ""
- else:
- # Neutral
- price_color = Fore.YELLOW
- good_color = Fore.YELLOW
- price_indicator = ""
- # Display the good with appropriate colors
- fast_print(f"{good_color}{good}{Style.RESET_ALL}: {price_color}${price}{Style.RESET_ALL} {price_indicator} "
- f"(Supply: {supply}, Demand: {demand}, Weight: {weight} units, Max Cargo: {max_fit})")
- # Display Relationship with the current town
- slow_print(f"\n{Fore.GREEN}Relationship with {self.town}:{Style.RESET_ALL}")
- aspects = self.player.relationships[self.town]
- # Display Overall Relationship Status
- overall_status = self.player.get_overall_relationship_status(self.town)
- if overall_status in ["Ally", "Friendly"]:
- status_color = Fore.GREEN
- elif overall_status in ["Hostile", "Enemy"]:
- status_color = Fore.RED
- else:
- status_color = Fore.YELLOW
- slow_print(f" Overall Relationship: {status_color}{overall_status}{Style.RESET_ALL}")
- # Display individual aspects
- for aspect, score in aspects.items():
- if score >= 40:
- aspect_color = Fore.GREEN
- elif score >= 20:
- aspect_color = Fore.BLUE
- elif score >= 0:
- aspect_color = Fore.YELLOW
- elif score <= -30:
- aspect_color = Fore.RED
- elif score <= -20:
- aspect_color = Fore.MAGENTA
- else:
- aspect_color = Fore.YELLOW
- fast_print(f" {Fore.CYAN}{aspect}:{Style.RESET_ALL} {aspect_color}{score}{Style.RESET_ALL}")
- print()
- def process_ai_traders(self):
- """Processes all AI traders' actions for the market."""
- for trader in self.ai_traders:
- trader.perform_action(self)
- # After AI traders have acted, regenerate prices
- self.generate_prices()
- class Game:
- """Represents the main game loop and logic."""
- def __init__(self):
- # Difficulty selection will be done in start()
- self.player = None
- self.difficulty = None
- self.starting_money = None # Will be set during game start
- self.turns_total = 0
- self.markets = {}
- self.current_market = None
- self.current_event = None
- self.pandemic_applied = False # Add this flag to track pandemic impact
- # Define decay rates to return supply and demand towards base values
- self.supply_decay_rate = 0.03 # Reduced decay rate for slower stabilization
- self.demand_decay_rate = 0.03 # Reduced decay rate for slower stabilization
- self.turn_counter = 1
- self.relation_multiplier = 1.5 # Adjust this value as desired
- self.game_over = False
- self.key_events = [] # To track key events for summary
- # New variables to track per-turn actions
- self.network_used = False # To track if NETWORK command has been used in the current turn
- self.consecutive_travels = 0 # To track consecutive travels
- self.last_command = None # To track the last command issued by the player
- def choose_difficulty(self):
- """Allows the player to choose a difficulty level."""
- fast_print("\nChoose Difficulty Level:")
- for idx, level in enumerate(DIFFICULTIES.keys(), 1):
- fast_print(f"{idx}. {level.capitalize()}")
- while True:
- choice = input(f"Enter the number corresponding to your choice (1-{len(DIFFICULTIES)}): ").strip()
- if choice.isdigit() and 1 <= int(choice) <= len(DIFFICULTIES):
- selected = list(DIFFICULTIES.keys())[int(choice)-1]
- fast_print(f"Selected {selected.capitalize()} difficulty.\n")
- return selected
- else:
- fast_print("Invalid choice. Please try again.")
- def start(self):
- """Starts the game by displaying the title and welcome message."""
- fast_print(TITLE)
- # Print the '=' lines separately in yellow without extra line breaks
- fast_print(f"""{Fore.YELLOW}{'='*60}{Style.RESET_ALL}""")
- medium_print(WELCOME_TEXT)
- fast_print(f"""{Fore.YELLOW}{'='*60}{Style.RESET_ALL}""")
- # Now choose difficulty
- self.difficulty = self.choose_difficulty()
- # Initialize player and markets after difficulty is chosen
- self.starting_money = DIFFICULTIES[self.difficulty]["starting_money"]
- self.player = Player(
- starting_money=self.starting_money,
- starting_cargo=DIFFICULTIES[self.difficulty]["starting_cargo"],
- game=self # Pass the game instance
- )
- self.turns_total = DIFFICULTIES[self.difficulty]["turns"]
- self.markets = {town: Market(town, self.player) for town in TOWNS}
- self.current_market = self.markets[self.player.location]
- input("Press Enter to start your trading adventure...")
- self.game_loop()
- def game_loop(self):
- """Main game loop that runs until the player runs out of turns or exits."""
- while self.turn_counter <= self.turns_total and not self.game_over:
- # Start of turn
- medium_print(f"\n--- Turn {self.turn_counter}/{self.turns_total} ---")
- # Reset per-turn flags
- self.network_used = False # Reset NETWORK usage at the start of each turn
- # Handle consecutive traveling
- if self.last_command != "TRAVEL":
- self.consecutive_travels = 0 # Reset counter if player did something else
- self.last_command = None # Reset last command at the start of the turn
- # Display player status (excluding relationships)
- self.player.status_short()
- # Display prices for the current market
- self.current_market.display_prices()
- turn_consumed = False
- while not turn_consumed and not self.game_over:
- command = input("Enter command (BUY/SELL/TRAVEL/STATUS/UPGRADE/NETWORK/HELP/EXIT): ").strip().upper()
- while command not in ["BUY", "SELL", "TRAVEL", "STATUS", "UPGRADE", "NETWORK", "HELP", "EXIT"]:
- slow_print("ERROR: Invalid Input")
- command = input("Enter command (BUY/SELL/TRAVEL/STATUS/UPGRADE/NETWORK/HELP/EXIT): ").strip().upper()
- self.last_command = command # Store the last command
- if command == "STATUS":
- self.player.status()
- elif command == "NETWORK":
- if not self.network_used:
- self.check_network()
- self.network_used = True # Mark as used for this turn
- else:
- slow_print("You have already used the NETWORK command this turn.")
- elif command == "HELP":
- print(f"{Fore.YELLOW}{'='*60}{Style.RESET_ALL}")
- fast_print(HELP_TEXT)
- print(f"{Fore.YELLOW}{'='*60}{Style.RESET_ALL}")
- elif command == "EXIT":
- slow_print("Thank you for playing!")
- self.end_game()
- return # Exit the game loop
- elif command in ["BUY", "SELL", "TRAVEL", "UPGRADE"]:
- # Process commands that consume a turn
- if command == "BUY":
- action_successful = self.buy()
- turn_consumed = action_successful
- elif command == "SELL":
- action_successful = self.sell()
- turn_consumed = action_successful
- elif command == "TRAVEL":
- action_successful, turn_consumed = self.travel()
- elif command == "UPGRADE":
- action_successful = self.player.upgrade_cargo()
- turn_consumed = action_successful
- if action_successful:
- if turn_consumed:
- # At this point, a turn has passed
- # Process AI traders and events
- self.apply_decay()
- # Process AI traders for all markets
- for market in self.markets.values():
- market.process_ai_traders()
- # Trigger event before displaying prices
- self.trigger_event()
- # Regenerate prices after events
- self.current_market.generate_prices()
- self.turn_counter += 1
- # Apply relationship decay every 5 turns
- if self.turn_counter % 5 == 0:
- self.apply_relationship_decay()
- # Check if the game should end after the turn
- if self.turn_counter > self.turns_total:
- self.game_over = True # Set game over to True
- break # Break out of the inner while loop
- else:
- # Action was successful, but turn was not consumed (e.g., free travel)
- # Display the player's status and market overview at the new location
- self.player.status_short()
- self.current_market.display_prices()
- else:
- # Action failed; inform player and allow them to try again
- slow_print("Action could not be completed. Please choose another action.")
- # Do not consume turn
- else:
- # Invalid command (shouldn't reach here due to earlier validation)
- slow_print("ERROR: Invalid Input")
- # After the loop ends, call end_game
- self.end_game()
- return # Ensure the method exits after ending the game
- def choose_good(self, action):
- """Prompts the player to choose a good to buy or sell."""
- fast_print("Available goods:")
- all_goods = list(ALL_GOODS.keys())
- while True:
- for idx, good in enumerate(all_goods, 1):
- fast_print(f"{idx}. {good}")
- choice = input(f"Enter the number of the good to {action}: ").strip()
- if not choice.isdigit() or not (1 <= int(choice) <= len(all_goods)):
- slow_print("ERROR: Invalid Input. Please enter a valid number.")
- continue
- return all_goods[int(choice) - 1]
- def check_network(self):
- """Provides rumors about the status of other towns in the merchant network."""
- medium_print(f"\n{Fore.GREEN}Merchant Network Rumors:{Style.RESET_ALL}")
- for town, market in self.markets.items():
- status = self.player.get_overall_relationship_status(town)
- rumor = self.generate_rumor(town, market, status)
- if status in ["Ally", "Friendly"]:
- color = Fore.CYAN
- elif status in ["Hostile", "Enemy"]:
- color = Fore.RED
- else:
- color = Fore.YELLOW
- fast_print(f"{color}{town}:{Style.RESET_ALL}")
- fast_print(f" {rumor}")
- print()
- def generate_rumor(self, town, market, status):
- """Generates a rumor based on the town's market and relationship status."""
- # Base rumor based on relationship
- if status == "Ally":
- base_rumor = f"{Fore.BLUE}is thriving and their trade is booming.{Style.RESET_ALL}"
- elif status == "Friendly":
- base_rumor = f"{Fore.GREEN}is experiencing steady trade.{Style.RESET_ALL}"
- elif status == "Neutral":
- base_rumor = f"{Fore.YELLOW}has a balanced market.{Style.RESET_ALL}"
- elif status == "Hostile":
- base_rumor = f"{Fore.RED}is facing some challenges, causing minor disruptions in trade.{Style.RESET_ALL}"
- else: # Enemy
- base_rumor = f"{Fore.RED}is in turmoil, significantly affecting their market and relations.{Style.RESET_ALL}"
- # Select multiple goods to include in the rumor
- affected_goods = random.sample(list(ALL_GOODS.keys()), k=random.randint(1, 3)) # Affect 1 to 3 goods
- goods_rumors = []
- for good in affected_goods:
- supply = market.supply.get(good, 0)
- demand = market.demand.get(good, 0)
- good_colored = f"{Fore.CYAN}{good}{Style.RESET_ALL}"
- if demand > supply * 1.5:
- # High demand pushing prices up
- rumor_text = f"high demand for {good_colored} is pushing prices up"
- rumor_colored = f"{Fore.RED}{rumor_text}{Style.RESET_ALL}"
- goods_rumors.append(rumor_colored)
- elif demand < supply * 0.5:
- # Excess supply lowering prices
- rumor_text = f"excess supply of {good_colored} is lowering prices"
- rumor_colored = f"{Fore.GREEN}{rumor_text}{Style.RESET_ALL}"
- goods_rumors.append(rumor_colored)
- else:
- # Stable demand and supply
- rumor_text = f"stable demand and supply for {good_colored}"
- rumor_colored = f"{Fore.YELLOW}{rumor_text}{Style.RESET_ALL}"
- goods_rumors.append(rumor_colored)
- goods_rumor = "; ".join(goods_rumors)
- rumor = f"{base_rumor} Additionally, there's {goods_rumor}."
- return rumor
- def buy(self):
- """Handles the buying process for the player."""
- while True:
- good = self.choose_good("buy")
- if not good:
- return False # Indicate that no transaction occurred
- price = self.current_market.prices.get(good, GOODS.get(good, {}).get("base_price", 100))
- # Calculate max affordable based on money
- max_affordable_quantity = self.player.money // price
- # Calculate max based on cargo
- if good in GOODS:
- good_weight = GOODS[good]["weight"]
- else:
- good_weight = 5 # Default weight
- available_cargo_space = self.player.max_cargo - self.player.current_cargo
- max_cargo_quantity = available_cargo_space // good_weight
- # Calculate max based on supply
- max_supply = int(self.current_market.supply.get(good, 0))
- max_quantity = min(max_affordable_quantity, max_cargo_quantity, max_supply)
- if max_quantity <= 0:
- slow_print("You cannot buy any units of this good due to insufficient funds, cargo space, or supply.")
- return False # Indicate that no transaction occurred
- # Encourage bulk buying with discounts
- discount = 0
- discounted_price = price
- if max_quantity >= 20:
- discount = 0.10 # 10% discount for buying 20 or more units
- discounted_price = int(price * (1 - discount))
- fast_print(f"Bulk purchase discount applied! Price per unit: ${discounted_price} (Original: ${price})")
- elif max_quantity >= 10:
- discount = 0.05 # 5% discount for buying 10 or more units
- discounted_price = int(price * (1 - discount))
- fast_print(f"Bulk purchase discount applied! Price per unit: ${discounted_price} (Original: ${price})")
- fast_print(f"You can afford up to {max_quantity} units based on your constraints.")
- while True:
- quantity_input = input(f"Enter the quantity of {good} to buy (max {max_quantity}): ").strip()
- if not quantity_input.isdigit():
- slow_print("ERROR: Invalid input. Please enter a valid number.")
- continue # Prompt again
- quantity = int(quantity_input)
- if quantity <= 0 or quantity > max_quantity:
- slow_print("ERROR: Quantity must be a positive number within your maximum limit.")
- continue # Prompt again
- cost = discounted_price * quantity
- success, added_weight = self.player.add_cargo(good, quantity)
- if not success:
- slow_print(f"Cannot buy {quantity} {good}. Exceeds cargo capacity.")
- return False # Indicate that no transaction occurred
- # Update player and market
- self.player.money -= cost
- self.current_market.supply[good] -= quantity
- self.current_market.demand[good] += quantity * 0.4 # Increased impact
- slow_print(f"Bought {quantity} {good} for ${cost}.")
- fast_print(f"Cargo Updated: {self.player.current_cargo}/{self.player.max_cargo} units used.")
- self.player.event_log.append(f"Turn {self.turn_counter}: Bought {quantity} {good} for ${cost}.")
- self.key_events.append(f"Turn {self.turn_counter}: Bought {quantity} {good} for ${cost}.")
- # Relationship modifications based on goods categories
- self.update_relationships_after_purchase(good, quantity)
- return True # Indicate that the transaction was successful
- def sell(self):
- """Handles the selling process for the player."""
- while True:
- good = self.choose_good("sell")
- if not good:
- return False # Indicate that no transaction occurred
- if self.player.inventory.get(good, 0) == 0:
- fast_print(f"You have no {good} to sell.")
- return False # Indicate that no transaction occurred
- max_sell_quantity = int(self.player.inventory.get(good, 0))
- fast_print(f"You can sell up to {max_sell_quantity} units based on your inventory.")
- while True:
- quantity_input = input(f"Enter the quantity of {good} to sell (max {max_sell_quantity}): ").strip()
- if not quantity_input.isdigit():
- slow_print("ERROR: Invalid input. Please enter a valid number.")
- continue # Prompt again
- quantity = int(quantity_input)
- if quantity <= 0 or quantity > max_sell_quantity:
- slow_print("ERROR: Quantity must be a positive number within your maximum limit.")
- continue # Prompt again
- price = self.current_market.prices.get(good, GOODS.get(good, {}).get("base_price", 100))
- revenue = price * quantity
- # Update player and market
- self.player.money += revenue
- self.player.remove_cargo(good, quantity)
- self.current_market.supply[good] += quantity
- self.current_market.demand[good] -= quantity * 0.4 # Increased impact
- slow_print(f"Sold {quantity} {good} for ${revenue}.")
- fast_print(f"Cargo Updated: {self.player.current_cargo}/{self.player.max_cargo} units used.")
- self.player.event_log.append(f"Turn {self.turn_counter}: Sold {quantity} {good} for ${revenue}.")
- self.key_events.append(f"Turn {self.turn_counter}: Sold {quantity} {good} for ${revenue}.")
- # Relationship modifications based on goods categories
- self.update_relationships_after_sale(good, quantity)
- return True # Indicate that the transaction was successful
- def travel(self):
- """Handles the travel process for the player to move between towns."""
- available_towns = [town for town in TOWNS if town != self.player.location]
- slow_print("\nAvailable towns to travel to:")
- while True:
- for idx, town in enumerate(available_towns, 1):
- fast_print(f"{idx}. {town}")
- choice = input(f"Enter the number of the town you want to travel to (1-{len(available_towns)}): ").strip()
- if not choice.isdigit() or not (1 <= int(choice) <= len(available_towns)):
- slow_print("ERROR: Invalid Input. Please enter a valid number.")
- continue
- new_location = available_towns[int(choice) - 1]
- break
- self.player.location = new_location
- self.player.visited_towns.add(new_location) # Ensure the new town is marked as visited
- self.current_market = self.markets[new_location]
- slow_print(f"Traveled to {new_location}.")
- self.player.event_log.append(f"Turn {self.turn_counter}: Traveled to {new_location}.")
- self.key_events.append(f"Turn {self.turn_counter}: Traveled to {new_location}.")
- # Update consecutive travel counter
- self.consecutive_travels += 1
- # Apply penalties only if player has traveled multiple turns in a row
- if self.consecutive_travels >= 3:
- penalty_trade = -7 # Increased penalty
- penalty_reputation = -5
- penalty_favor = -3
- self.player.modify_relationship(new_location, "Trade", penalty_trade)
- self.player.modify_relationship(new_location, "Reputation", penalty_reputation)
- self.player.modify_relationship(new_location, "Favor", penalty_favor)
- slow_print(f"Frequent traveling has significantly strained your relationships with {new_location}.")
- self.player.event_log.append(f"Turn {self.turn_counter}: Frequent traveling strained relationships with {new_location}.")
- self.key_events.append(f"Turn {self.turn_counter}: Frequent traveling strained relationships with {new_location}.")
- else:
- # No penalty applied
- pass
- # Check for free travel
- if hasattr(self.player, 'free_travel') and self.player.free_travel:
- slow_print("Due to favorable winds, your travel was faster!")
- self.player.free_travel = False # Reset free travel
- return (True, False) # Action successful, turn not consumed
- return (True, True) # Action successful, turn consumed
- def apply_event(self, event, global_event=False):
- """Applies the effects of a triggered event to the game."""
- slow_print(f"\nEvent: {event}")
- # Positive Global Events
- if event == "A global trade agreement has been signed, reducing tariffs.":
- slow_print("Tariffs reduced globally! Prices for goods decrease significantly.")
- for market in self.markets.values():
- for good in GOODS:
- market.prices[good] = int(market.prices[good] * 0.90)
- self.player.modify_relationship(self.player.location, "Trade", 15) # Increased impact
- self.player.reputation += 10
- self.key_events.append(f"Turn {self.turn_counter}: Global trade agreement reduced tariffs.")
- return
- if event == "Technological advancements have improved trade efficiency worldwide.":
- slow_print("Trade efficiency improved globally! Increased supply of goods.")
- for market in self.markets.values():
- for good in GOODS:
- market.supply[good] += 100
- self.player.modify_relationship(self.player.location, "Reputation", 15) # Increased impact
- self.player.reputation += 10
- self.key_events.append(f"Turn {self.turn_counter}: Technological advancements improved trade efficiency.")
- return
- if event == "A global festival increases demand for luxury goods.":
- slow_print("Global festival! Demand and prices for luxury goods increase.")
- luxury_goods = ["Silk", "Wine", "Gold"]
- for market in self.markets.values():
- for good in luxury_goods:
- market.demand[good] += 150
- market.prices[good] = int(market.prices[good] * 1.3)
- self.player.modify_relationship(self.player.location, "Favor", 15) # Increased impact
- self.player.reputation += 10
- self.key_events.append(f"Turn {self.turn_counter}: Global festival increased demand for luxury goods.")
- return
- # Positive Local Events
- if event == "You found a hidden stash of goods in the market!":
- found_good = random.choice(list(GOODS.keys()))
- found_quantity = random.randint(15, 25)
- added_weight = GOODS[found_good]["weight"] * found_quantity
- if self.player.current_cargo + added_weight <= self.player.max_cargo:
- self.player.add_cargo(found_good, found_quantity)
- slow_print(f"You found {found_quantity} units of {found_good} and added them to your inventory!")
- self.player.modify_relationship(self.player.location, "Favor", 15) # Increased impact
- self.player.reputation += 10
- self.key_events.append(f"Turn {self.turn_counter}: Found {found_quantity} {found_good} in the market.")
- else:
- slow_print(f"You found {found_quantity} units of {found_good}, but lack the cargo space to carry them.")
- return
- if event == "A wealthy patron gifts you valuable items!":
- gifted_good = random.choice(["Gems", "Gold", "Silk"])
- gifted_quantity = random.randint(10, 15)
- added_weight = GOODS[gifted_good]["weight"] * gifted_quantity
- if self.player.current_cargo + added_weight <= self.player.max_cargo:
- self.player.add_cargo(gifted_good, gifted_quantity)
- slow_print(f"A wealthy patron gifted you {gifted_quantity} units of {gifted_good}!")
- self.player.modify_relationship(self.player.location, "Favor", 20) # Increased impact
- self.player.reputation += 15
- self.key_events.append(f"Turn {self.turn_counter}: Received {gifted_quantity} {gifted_good} from a patron.")
- else:
- slow_print(f"A wealthy patron wanted to gift you {gifted_quantity} units of {gifted_good}, but you lacked the cargo space.")
- return
- if event == "Your reputation has earned you a local tax exemption!":
- saved_amount = 300
- self.player.money += saved_amount
- slow_print(f"You received a local tax exemption and saved ${saved_amount}!")
- self.player.modify_relationship(self.player.location, "Reputation", 20) # Increased impact
- self.player.reputation += 15
- self.key_events.append(f"Turn {self.turn_counter}: Received tax exemption, saved ${saved_amount}.")
- return
- if event == "A local festival boosts demand and prices for certain goods.":
- festival_goods = random.sample(["Spices", "Wine", "Cloth", "Tea"], 2)
- for good in festival_goods:
- self.current_market.demand[good] += 120
- self.current_market.prices[good] = int(self.current_market.prices[good] * 1.5)
- slow_print(f"The local festival boosted demand and prices for {', '.join(festival_goods)}!")
- self.player.modify_relationship(self.player.location, "Favor", 15) # Increased impact
- self.player.reputation += 10
- self.key_events.append(f"Turn {self.turn_counter}: Festival boosted prices for {', '.join(festival_goods)}.")
- return
- if event == "Favorable winds reduce travel times temporarily.":
- slow_print("Favorable winds! You can travel without consuming a turn next time.")
- self.player.free_travel = True # Set attribute for free travel
- self.player.reputation += 5
- self.key_events.append(f"Turn {self.turn_counter}: Favorable winds will reduce next travel time.")
- return
- if event == "Merchants admire your honesty, improving relationships.":
- slow_print("Your honesty has impressed the merchants. Relationships have greatly improved.")
- self.player.modify_relationship(self.player.location, "Trade", 20) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", 20)
- self.player.reputation += 15
- self.key_events.append(f"Turn {self.turn_counter}: Honesty improved relationships in {self.player.location}.")
- return
- if event == "An influential guild offers you a partnership.":
- slow_print("An influential guild offers you a partnership, significantly increasing your cargo capacity.")
- self.player.max_cargo += 100 # Increased impact
- slow_print(f"Your cargo capacity increased to {self.player.max_cargo}.")
- self.player.modify_relationship(self.player.location, "Trade", 20) # Increased impact
- self.player.reputation += 15
- self.key_events.append(f"Turn {self.turn_counter}: Guild partnership increased cargo capacity.")
- return
- if event == "An overstock in the market reduces prices for certain goods.":
- overstock_goods = random.sample(["Food", "Iron", "Herbs"], 2)
- for good in overstock_goods:
- self.current_market.supply[good] += 150
- self.current_market.prices[good] = int(self.current_market.prices[good] * 0.6)
- slow_print(f"Overstock in the market! Prices for {', '.join(overstock_goods)} have decreased.")
- self.player.modify_relationship(self.player.location, "Favor", 15) # Increased impact
- self.player.reputation += 10
- self.key_events.append(f"Turn {self.turn_counter}: Overstock reduced prices for {', '.join(overstock_goods)}.")
- return
- if event == "Local artisans gift you exquisite items to trade.":
- gifted_good = random.choice(["Silk", "Cloth", "Wine"])
- gifted_quantity = random.randint(15, 25)
- added_weight = GOODS[gifted_good]["weight"] * gifted_quantity
- if self.player.current_cargo + added_weight <= self.player.max_cargo:
- self.player.add_cargo(gifted_good, gifted_quantity)
- slow_print(f"Local artisans gifted you {gifted_quantity} units of {gifted_good}!")
- self.player.modify_relationship(self.player.location, "Favor", 20) # Increased impact
- self.player.reputation += 15
- self.key_events.append(f"Turn {self.turn_counter}: Artisans gifted {gifted_quantity} {gifted_good}.")
- else:
- slow_print(f"Local artisans wanted to gift you {gifted_quantity} units of {gifted_good}, but you lacked the cargo space.")
- return
- if event == "Successful mediation improves trade relations between towns.":
- slow_print("Your mediation greatly improved trade relations between towns.")
- for town in TOWNS:
- self.player.modify_relationship(town, "Trade", 15) # Increased impact
- self.player.reputation += 20
- self.key_events.append(f"Turn {self.turn_counter}: Mediation improved trade relations universally.")
- return
- # Negative Global Events
- if event == "Global trade embargo reducing supply worldwide.":
- slow_print("A global trade embargo has been enacted. Supply of goods has decreased significantly worldwide.")
- for market in self.markets.values():
- for good in GOODS:
- market.supply[good] = max(10, market.supply[good] - 100)
- market.prices[good] = int(market.prices[good] * 1.2)
- self.player.modify_relationship(self.player.location, "Trade", -15) # Increased impact
- self.player.reputation -= 10
- self.key_events.append(f"Turn {self.turn_counter}: Global trade embargo reduced supply.")
- return
- if event == "Pandemic affecting demand for certain goods globally.":
- slow_print("A pandemic has severely reduced global demand for certain goods.")
- affected_goods = ["Spices", "Wine", "Silk"]
- for market in self.markets.values():
- for good in affected_goods:
- market.demand[good] = max(50, market.demand.get(good, 0) - 150)
- market.prices[good] = int(market.prices[good] * 0.7)
- # Move relationship modification outside the loop
- self.player.modify_relationship(self.player.location, "Reputation", -15)
- self.player.reputation -= 10
- self.key_events.append(f"Turn {self.turn_counter}: Pandemic reduced demand for certain goods.")
- return
- if event == "Global inflation increasing prices across the board.":
- slow_print("Global inflation is significantly increasing prices everywhere.")
- for market in self.markets.values():
- for good in GOODS:
- market.prices[good] = int(market.prices[good] * 1.3)
- self.player.modify_relationship(self.player.location, "Trade", -15) # Increased impact
- self.player.reputation -= 10
- self.key_events.append(f"Turn {self.turn_counter}: Global inflation increased prices.")
- return
- if event == "Global recession decreasing purchasing power.":
- slow_print("A global recession has severely decreased purchasing power.")
- for market in self.markets.values():
- for good in GOODS:
- market.demand[good] = max(50, market.demand[good] - 120)
- market.prices[good] = int(market.prices[good] * 0.8)
- self.player.modify_relationship(self.player.location, "Trade", -15) # Increased impact
- self.player.reputation -= 10
- self.key_events.append(f"Turn {self.turn_counter}: Global recession decreased purchasing power.")
- return
- # Negative Local Events
- if event == "Thieves attacked your caravan and stole some goods!":
- affected_good = random.choice(list(ALL_GOODS.keys()))
- stolen_qty = random.randint(10, 20)
- actual_stolen = min(stolen_qty, self.player.inventory.get(affected_good, 0))
- self.player.remove_cargo(affected_good, actual_stolen)
- slow_print(f"Thieves stole {actual_stolen} units of {affected_good} from your caravan!")
- self.player.modify_relationship(self.player.location, "Trade", -20) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -15)
- self.player.modify_relationship(self.player.location, "Favor", -10)
- self.player.reputation -= 25
- self.key_events.append(f"Turn {self.turn_counter}: Thieves stole {actual_stolen} {affected_good}.")
- return
- if event == "A storm ruined your goods during travel.":
- damaged_good = random.choice(list(ALL_GOODS.keys()))
- damaged_qty = random.randint(10, 20)
- actual_damaged = min(damaged_qty, self.player.inventory.get(damaged_good, 0))
- self.player.remove_cargo(damaged_good, actual_damaged)
- slow_print(f"A storm damaged {actual_damaged} units of {damaged_good} in your cargo.")
- self.player.modify_relationship(self.player.location, "Trade", -15) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -10)
- self.player.modify_relationship(self.player.location, "Favor", -7)
- self.player.reputation -= 20
- self.key_events.append(f"Turn {self.turn_counter}: Storm damaged {actual_damaged} {damaged_good}.")
- return
- if event == "Disease outbreak decreased the demand for food.":
- affected_good = "Food"
- price_drop = int(GOODS[affected_good]["base_price"] * 0.35)
- self.current_market.demand[affected_good] = max(50, self.current_market.demand.get(affected_good, 0) - 150)
- self.current_market.prices[affected_good] = max(Market.PRICE_FLOOR, self.current_market.prices.get(affected_good, 0) - price_drop)
- slow_print(f"A disease outbreak severely decreased the demand for {affected_good}, lowering its price by ${price_drop}.")
- self.player.modify_relationship(self.player.location, "Trade", -18) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -12)
- self.player.reputation -= 25
- self.key_events.append(f"Turn {self.turn_counter}: Disease outbreak decreased demand for {affected_good}.")
- return
- if event == "Pirates disrupted trade in the seas.":
- affected_good = random.choice(list(ALL_GOODS.keys()))
- price_increase = int(GOODS[affected_good]["base_price"] * 0.45)
- self.current_market.supply[affected_good] = max(10, self.current_market.supply.get(affected_good, 0) - 100)
- self.current_market.prices[affected_good] = min(Market.PRICE_CEILING, self.current_market.prices.get(affected_good, 0) + price_increase)
- slow_print(f"Pirates severely disrupted trade, decreasing supply and increasing price of {affected_good} by ${price_increase}.")
- self.player.modify_relationship(self.player.location, "Trade", -18) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -12)
- self.player.modify_relationship(self.player.location, "Favor", -8)
- self.player.reputation -= 25
- self.key_events.append(f"Turn {self.turn_counter}: Pirates disrupted trade, affected {affected_good}.")
- return
- if event == "Government imposed a tax on trade.":
- tax_amount = 200
- self.player.money = max(0, self.player.money - tax_amount)
- slow_print(f"The government imposed a heavy tax on your trade. You lost ${tax_amount}.")
- self.player.modify_relationship(self.player.location, "Trade", -18) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -12)
- self.player.reputation -= 20
- self.key_events.append(f"Turn {self.turn_counter}: Government taxed you ${tax_amount}.")
- return
- if event == "Locusts devastated the food supplies in Dusktown.":
- affected_good = "Food"
- damage = random.randint(15, 25)
- actual_damaged = min(damage, self.player.inventory.get(affected_good, 0))
- if self.player.location == "Dusktown":
- self.player.remove_cargo(affected_good, actual_damaged)
- slow_print(f"Locusts devastated food supplies in Dusktown, destroying {actual_damaged} units of your {affected_good}.")
- self.player.modify_relationship(self.player.location, "Trade", -15) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -10)
- self.player.modify_relationship(self.player.location, "Favor", -7)
- self.player.reputation -= 20
- self.key_events.append(f"Turn {self.turn_counter}: Locusts destroyed {actual_damaged} {affected_good} in Dusktown.")
- else:
- slow_print("Locusts devastated food supplies in Dusktown.")
- return
- if event == "Bandit attack in Oakwood stole some of your goods.":
- affected_good = random.choice(list(ALL_GOODS.keys()))
- stolen_qty = random.randint(10, 20)
- actual_stolen = min(stolen_qty, self.player.inventory.get(affected_good, 0))
- if self.player.location == "Oakwood":
- self.player.remove_cargo(affected_good, actual_stolen)
- slow_print(f"Bandits in Oakwood stole {actual_stolen} units of your {affected_good}.")
- self.player.modify_relationship(self.player.location, "Trade", -20) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -15)
- self.player.modify_relationship(self.player.location, "Favor", -10)
- self.player.reputation -= 25
- self.key_events.append(f"Turn {self.turn_counter}: Bandits in Oakwood stole {actual_stolen} {affected_good}.")
- else:
- slow_print("Bandits attacked traders in Oakwood.")
- return
- if event == "Natural disaster in Dusktown affecting multiple goods.":
- affected_goods = random.sample(list(ALL_GOODS.keys()), k=3)
- if self.player.location == "Dusktown":
- for good in affected_goods:
- damaged_qty = random.randint(10, 20)
- actual_damaged = min(damaged_qty, self.player.inventory.get(good, 0))
- self.player.remove_cargo(good, actual_damaged)
- slow_print(f"A natural disaster in Dusktown damaged a significant amount of your goods.")
- self.player.modify_relationship(self.player.location, "Trade", -25) # Increased impact
- self.player.modify_relationship(self.player.location, "Reputation", -18)
- self.player.modify_relationship(self.player.location, "Favor", -12)
- self.player.reputation -= 30
- self.key_events.append(f"Turn {self.turn_counter}: Natural disaster damaged goods in Dusktown.")
- else:
- slow_print("A natural disaster struck Dusktown, severely affecting trade.")
- return
- # Fallback for unhandled events
- slow_print("An unusual event occurred, but nothing notable happened.")
- def trigger_event(self):
- """Randomly triggers a global or local event based on difficulty settings."""
- event_chance = DIFFICULTIES[self.difficulty]["event_chance"]
- # Reduce event chance based on reputation
- reputation_factor = 1 - (self.player.reputation / 200) # Adjust as needed
- reputation_factor = max(0.5, reputation_factor) # Ensure at least 50% of base chance
- adjusted_event_chance = event_chance * reputation_factor
- if random.random() < adjusted_event_chance:
- event_type = random.choice(["GLOBAL", "LOCAL"])
- if event_type == "GLOBAL":
- event = random.choice(GLOBAL_EVENTS)
- slow_print(f"\n{Fore.RED}Global Event: {event}{Style.RESET_ALL}")
- if "Pandemic" in event:
- if not hasattr(self, "pandemic_applied") or not self.pandemic_applied:
- self.apply_event(event, global_event=True)
- self.pandemic_applied = True # Set the flag to prevent multiple applications
- else:
- self.apply_event(event, global_event=True)
- else:
- event = random.choice(LOCAL_EVENTS)
- slow_print(f"\n{Fore.RED}Local Event: {event}{Style.RESET_ALL}")
- self.apply_event(event, global_event=False)
- # Reset the pandemic flag if not used
- if not hasattr(self, "pandemic_applied"):
- self.pandemic_applied = False # Initialize if it doesn't exist
- def apply_relationship_decay(self):
- """Gradually decays the relationships over time."""
- medium_print("\nRelationships have naturally changed over time:")
- for town in TOWNS:
- aspects = self.player.relationships[town]
- for aspect in aspects:
- original_score = aspects[aspect]
- if aspects[aspect] > 0:
- aspects[aspect] -= 2 # Increased decay rate
- elif aspects[aspect] < 0:
- aspects[aspect] += 2 # Increased recovery rate
- # Clamp values
- aspects[aspect] = max(RELATIONSHIP_MIN, min(aspects[aspect], RELATIONSHIP_MAX))
- change = aspects[aspect] - original_score
- if change != 0:
- # Notify the player about the change
- if change > 0:
- medium_print(f"[{town} - {aspect}] Improved by {change} point(s).")
- else:
- medium_print(f"[{town} - {aspect}] Decreased by {-change} point(s).")
- def update_relationships_after_purchase(self, good, quantity):
- town = self.player.location
- price = self.current_market.prices.get(good, GOODS[good]["base_price"])
- # Introduce balanced scaling factor
- scaling_factor = 1 + (price / 500) # Scales relationship changes with price
- scaling_factor = min(2.0, scaling_factor) # Cap scaling factor to avoid excessive influence
- max_increase = 15 # Cap on the maximum relationship improvement per transaction
- relationship_change = min(int(quantity * scaling_factor), max_increase)
- if good in SUPPORTIVE_GOODS:
- self.player.modify_relationship(town, "Reputation", relationship_change)
- elif good in STRATEGIC_GOODS:
- self.player.modify_relationship(town, "Trade", relationship_change)
- elif good in LUXURY_GOODS:
- self.player.modify_relationship(town, "Favor", relationship_change)
- def update_relationships_after_sale(self, good, quantity):
- town = self.player.location
- price = self.current_market.prices.get(good, GOODS[good]["base_price"])
- # Adjust scaling: more linear impact for sales
- scaling_factor = 0.8 + (price / 1000) # Lower scaling for sales
- scaling_factor = min(1.5, scaling_factor) # Cap scaling factor
- max_increase = 10 # Cap on the maximum relationship improvement per transaction
- relationship_change = min(int(quantity * scaling_factor), max_increase)
- if good in SUPPORTIVE_GOODS:
- self.player.modify_relationship(town, "Reputation", relationship_change)
- elif good in STRATEGIC_GOODS:
- self.player.modify_relationship(town, "Trade", relationship_change)
- elif good in LUXURY_GOODS:
- self.player.modify_relationship(town, "Favor", relationship_change)
- def apply_decay(self):
- """Applies decay to supply and demand in all markets to move towards base values."""
- for good, info in GOODS.items():
- for market in self.markets.values():
- # Supply decay towards base_supply
- if market.supply.get(good, 0) < info["base_supply"]:
- market.supply[good] += info["base_supply"] * self.supply_decay_rate
- if market.supply[good] > info["base_supply"]:
- market.supply[good] = info["base_supply"]
- elif market.supply.get(good, 0) > info["base_supply"]:
- market.supply[good] -= info["base_supply"] * self.supply_decay_rate
- if market.supply[good] < info["base_supply"]:
- market.supply[good] = info["base_supply"]
- # Demand decay towards base_demand
- if market.demand.get(good, 0) < info["base_demand"]:
- market.demand[good] += info["base_demand"] * self.demand_decay_rate
- if market.demand[good] > info["base_demand"]:
- market.demand[good] = info["base_demand"]
- elif market.demand.get(good, 0) > info["base_demand"]:
- market.demand[good] -= info["base_demand"] * self.demand_decay_rate
- if market.demand[good] < info["base_demand"]:
- market.demand[good] = info["base_demand"]
- # Additional decay for Gold's value to prevent hoarding
- if good == "Gold":
- market.prices["Gold"] = max(Market.PRICE_FLOOR, int(market.prices["Gold"] * 0.98)) # Increased depreciation per turn
- def end_game(self):
- """Displays the final game results and concludes the game."""
- slow_print("\nGame Over!")
- fast_print(f"Final Money: ${self.player.money}")
- total_goods = sum(self.player.inventory.values())
- fast_print(f"Total Goods: {total_goods}")
- net_worth = self.player.money + sum(
- self.player.inventory.get(good, 0) * self.current_market.prices.get(good, 0) for good in ALL_GOODS
- )
- fast_print(f"Net Worth: ${net_worth}")
- # Calculate financial performance
- financial_performance = self.calculate_financial_performance(net_worth)
- # Calculate social performance
- social_performance = self.calculate_social_performance()
- # Display financial performance
- slow_print(f"\n{Fore.GREEN}Financial Performance:{Style.RESET_ALL}")
- fast_print(f" - Net Worth Score: {financial_performance['net_worth_score']} / 5")
- fast_print(f" - Liquidity Score: {financial_performance['liquidity_score']} / 5")
- financial_total = financial_performance['net_worth_score'] + financial_performance['liquidity_score']
- fast_print(f" - Total Financial Score: {financial_total} / 10")
- # Display social performance
- slow_print(f"\n{Fore.BLUE}Social Performance (Relationships):{Style.RESET_ALL}")
- fast_print(f" - Average Trade Relations Score: {social_performance['trade_score']} / 5")
- fast_print(f" - Average Reputation Score: {social_performance['reputation_score']} / 5")
- fast_print(f" - Average Favor Score: {social_performance['favor_score']} / 5")
- fast_print(f" - Relationship Status Influence Score: {social_performance['status_score']} / 5") # New Line
- social_total = social_performance['trade_score'] + social_performance['reputation_score'] + social_performance['favor_score'] + social_performance['status_score'] # Updated
- fast_print(f" - Total Social Score: {social_total} / 20") # Updated
- # Calculate total score
- total_score = financial_total + social_total
- max_total_score = 10 + 20 # Financial max + Social max
- # Determine final rating based on total_score
- rating = self.determine_rating(total_score)
- rating_message = self.generate_final_message(financial_total, social_total, rating)
- slow_print(f"\nFinal Rating: {Fore.CYAN}{rating}{Style.RESET_ALL}")
- slow_print(rating_message)
- # Display key events summary
- slow_print("\nSummary of Your Journey:")
- for event in self.key_events:
- fast_print(event)
- # Removed the truncation with "..."
- # if len(self.key_events) > 50:
- # fast_print("...")
- # Display Relationship Status Summary
- slow_print("\nRelationship Status Summary:")
- status_counts = {
- "Ally": 0,
- "Friendly": 0,
- "Neutral": 0,
- "Hostile": 0,
- "Enemy": 0
- }
- for town in self.player.visited_towns:
- status = self.player.get_overall_relationship_status(town)
- if status in status_counts:
- status_counts[status] += 1
- for status, count in status_counts.items():
- color = Fore.GREEN if status == "Ally" else Fore.BLUE if status == "Friendly" else Fore.YELLOW if status == "Neutral" else Fore.RED if status in ["Hostile", "Enemy"] else Fore.WHITE
- fast_print(f"{color}{status}: {count}{Style.RESET_ALL}")
- slow_print("\nThank you for playing the Text-Based Trading Game!")
- sys.exit()
- def generate_final_message(self, financial_total, social_total, rating):
- """Generates a final message based on financial and social performance."""
- messages = {
- "Legendary": "Incredible! You became an unmatched trading legend with stellar relationships and unmatched wealth.",
- "Excellent": "Congratulations! You became a legendary trader with excellent relationships and strong financials.",
- "Great": "Outstanding! You achieved impressive wealth and maintained excellent relationships.",
- "Good": "Well done! You made a substantial profit and maintained good relationships.",
- "Decent": "You made a respectable profit and kept decent relations.",
- "Poor": "You faced challenges in trading, with room to improve both financially and socially.",
- "Terrible": "Your trading journey was fraught with difficulties. Significant improvement is needed in both trading and relationships."
- }
- # Customize the message based on which performance was better
- if financial_total > social_total:
- messages["Good"] += " Your financial acumen outshined your social engagements."
- messages["Decent"] += " You did well financially but could improve your relationships."
- messages["Poor"] += " Financial setbacks affected your journey more than social aspects."
- elif social_total > financial_total:
- messages["Good"] += " Your strong relationships boosted your trading journey."
- messages["Decent"] += " Your social skills helped balance financial challenges."
- messages["Poor"] += " Despite good relations, financial challenges hindered progress."
- return messages.get(rating, "")
- def calculate_net_worth_score(self, net_worth):
- """Assigns a score based on net worth."""
- if net_worth >= 40000:
- return 5
- elif net_worth >= 30000:
- return 4
- elif net_worth >= 20000:
- return 3
- elif net_worth >= 15000:
- return 2
- elif net_worth >= 10000:
- return 1
- else:
- return 0
- def calculate_trade_score(self, average_trade):
- """Assigns a score based on average Trade Relations."""
- if average_trade >= 60:
- return 5
- elif average_trade >= 40:
- return 4
- elif average_trade >= 20:
- return 3
- elif average_trade >= 10:
- return 2
- elif average_trade >= 0:
- return 1
- else:
- return 0
- def calculate_reputation_score(self, average_reputation):
- """Assigns a score based on average Reputation."""
- if average_reputation >= 60:
- return 5
- elif average_reputation >= 40:
- return 4
- elif average_reputation >= 20:
- return 3
- elif average_reputation >= 1:
- return 2
- elif average_reputation >= 0:
- return 1
- else:
- return 0
- def calculate_favor_score(self, average_favor):
- """Assigns a score based on average Favor."""
- if average_favor >= 60:
- return 5
- elif average_favor >= 40:
- return 4
- elif average_favor >= 20:
- return 3
- elif average_favor >= 10:
- return 2
- elif average_favor >= 0:
- return 1
- else:
- return 0
- def calculate_social_performance(self):
- """Calculates social performance metrics, including relationship statuses."""
- visited_towns = self.player.visited_towns
- if not visited_towns:
- visited_towns = {self.player.location} # Use a set for consistency
- # Calculate overall relationship scores for visited towns only
- total_trade = sum([self.player.relationships[town]["Trade"] for town in visited_towns])
- total_reputation = sum([self.player.relationships[town]["Reputation"] for town in visited_towns])
- total_favor = sum([self.player.relationships[town]["Favor"] for town in visited_towns])
- average_trade = total_trade / len(visited_towns)
- average_reputation = total_reputation / len(visited_towns)
- average_favor = total_favor / len(visited_towns)
- trade_score = self.calculate_trade_score(average_trade)
- reputation_score = self.calculate_reputation_score(average_reputation)
- favor_score = self.calculate_favor_score(average_favor)
- # Calculate relationship status influence score
- status_score = 0
- for town in visited_towns:
- status = self.player.get_overall_relationship_status(town)
- if status == "Ally":
- status_score += 3
- elif status == "Friendly":
- status_score += 2
- elif status == "Neutral":
- status_score += 1
- elif status == "Hostile":
- status_score -= 1
- elif status == "Enemy":
- status_score -= 2
- # Normalize status_score to a maximum of 5
- # Assuming maximum positive score is 3 * number of towns
- max_positive = 3 * len(visited_towns)
- if max_positive == 0:
- normalized_status_score = 0
- else:
- normalized_status_score = min(int((status_score / max_positive) * 5), 5)
- normalized_status_score = max(-5, normalized_status_score) # Clamp between -5 and 5
- # Convert negative scores to 0 for the scoring system
- if normalized_status_score < 0:
- normalized_status_score = 0
- elif normalized_status_score > 5:
- normalized_status_score = 5
- return {
- "trade_score": trade_score,
- "reputation_score": reputation_score,
- "favor_score": favor_score,
- "status_score": normalized_status_score # New field
- }
- def calculate_financial_performance(self, net_worth):
- """Calculates financial performance metrics."""
- # New liquidity ratio calculation based on starting money
- liquidity_ratio = self.player.money / self.player.starting_money
- liquidity_score = self.calculate_liquidity_score(liquidity_ratio)
- net_worth_score = self.calculate_net_worth_score(net_worth)
- return {
- "net_worth_score": net_worth_score,
- "liquidity_score": liquidity_score
- }
- def calculate_liquidity_score(self, liquidity_ratio):
- """
- Assigns a liquidity score based on the player's ending wealth relative to their starting wealth.
- Scales down the score the closer the ending wealth is to the starting wealth.
- """
- if liquidity_ratio >= 2.0: # Ending cash is at least double the starting cash
- return 5
- elif liquidity_ratio >= 1.8:
- return 4
- elif liquidity_ratio >= 1.5:
- return 3
- elif liquidity_ratio >= 1.2:
- return 2
- elif liquidity_ratio > 1.0:
- return 1 # Small improvement still earns a point
- else:
- return 0 # No score for failing to maintain starting wealth
- def determine_rating(self, total_score):
- """Determines the final rating based on total_score."""
- if total_score >= 30:
- return "Legendary"
- elif total_score >= 25:
- return "Excellent"
- elif total_score >= 20:
- return "Great"
- elif total_score >= 15:
- return "Good"
- elif total_score >= 10:
- return "Decent"
- elif total_score >= 5:
- return "Poor"
- else:
- return "Terrible"
- def generate_final_message(self, financial_total, social_total, rating):
- """Generates a final message based on financial and social performance."""
- messages = {
- "Legendary": "Incredible! You became an unmatched trading legend with stellar relationships and unmatched wealth.",
- "Excellent": "Congratulations! You became a legendary trader with excellent relationships and strong financials.",
- "Great": "Outstanding! You achieved impressive wealth or maintained excellent relationships.",
- "Good": "Well done! You made a substantial profit or maintained good relationships.",
- "Decent": "You made a respectable profit or kept decent relations.",
- "Poor": "You faced challenges in trading, with room to improve both financially and socially.",
- "Terrible": "Your trading journey was fraught with difficulties. Significant improvement is needed in both trading and relationships."
- }
- # Customize the message based on which performance was better
- if financial_total > social_total:
- messages["Good"] += " Your financial acumen outshined your social engagements."
- messages["Decent"] += " You did well financially but could improve your relationships."
- messages["Poor"] += " Financial setbacks affected your journey more than social aspects."
- elif social_total > financial_total:
- messages["Good"] += " Your strong relationships boosted your trading journey."
- messages["Decent"] += " Your social skills helped balance financial challenges."
- messages["Poor"] += " Despite good relations, financial challenges hindered progress."
- return messages.get(rating, "")
- def calculate_social_performance(self):
- """Calculates social performance metrics, including relationship statuses."""
- visited_towns = self.player.visited_towns
- if not visited_towns:
- visited_towns = {self.player.location} # Use a set for consistency
- # Calculate overall relationship scores for visited towns only
- total_trade = sum([self.player.relationships[town]["Trade"] for town in visited_towns])
- total_reputation = sum([self.player.relationships[town]["Reputation"] for town in visited_towns])
- total_favor = sum([self.player.relationships[town]["Favor"] for town in visited_towns])
- average_trade = total_trade / len(visited_towns)
- average_reputation = total_reputation / len(visited_towns)
- average_favor = total_favor / len(visited_towns)
- trade_score = self.calculate_trade_score(average_trade)
- reputation_score = self.calculate_reputation_score(average_reputation)
- favor_score = self.calculate_favor_score(average_favor)
- # Calculate relationship status influence score
- status_score = 0
- for town in visited_towns:
- status = self.player.get_overall_relationship_status(town)
- if status == "Ally":
- status_score += 3
- elif status == "Friendly":
- status_score += 2
- elif status == "Neutral":
- status_score += 1
- elif status == "Hostile":
- status_score -= 1
- elif status == "Enemy":
- status_score -= 2
- # Normalize status_score to a maximum of 5
- # Assuming maximum positive score is 3 * number of towns
- max_positive = 3 * len(visited_towns)
- if max_positive == 0:
- normalized_status_score = 0
- else:
- normalized_status_score = min(int((status_score / max_positive) * 5), 5)
- normalized_status_score = max(-5, normalized_status_score) # Clamp between -5 and 5
- # Convert negative scores to 0 for the scoring system
- if normalized_status_score < 0:
- normalized_status_score = 0
- elif normalized_status_score > 5:
- normalized_status_score = 5
- return {
- "trade_score": trade_score,
- "reputation_score": reputation_score,
- "favor_score": favor_score,
- "status_score": normalized_status_score # New field
- }
- def apply_decay(self):
- """Applies decay to supply and demand in all markets to move towards base values."""
- for good, info in GOODS.items():
- for market in self.markets.values():
- # Supply decay towards base_supply
- if market.supply.get(good, 0) < info["base_supply"]:
- market.supply[good] += info["base_supply"] * self.supply_decay_rate
- if market.supply[good] > info["base_supply"]:
- market.supply[good] = info["base_supply"]
- elif market.supply.get(good, 0) > info["base_supply"]:
- market.supply[good] -= info["base_supply"] * self.supply_decay_rate
- if market.supply[good] < info["base_supply"]:
- market.supply[good] = info["base_supply"]
- # Demand decay towards base_demand
- if market.demand.get(good, 0) < info["base_demand"]:
- market.demand[good] += info["base_demand"] * self.demand_decay_rate
- if market.demand[good] > info["base_demand"]:
- market.demand[good] = info["base_demand"]
- elif market.demand.get(good, 0) > info["base_demand"]:
- market.demand[good] -= info["base_demand"] * self.demand_decay_rate
- if market.demand[good] < info["base_demand"]:
- market.demand[good] = info["base_demand"]
- # Additional decay for Gold's value to prevent hoarding
- if good == "Gold":
- market.prices["Gold"] = max(Market.PRICE_FLOOR, int(market.prices["Gold"] * 0.98)) # Increased depreciation per turn
- def end_game(self):
- """Displays the final game results and concludes the game."""
- # The end_game method remains the same
- slow_print("\nGame Over!")
- fast_print(f"Final Money: ${self.player.money}")
- total_goods = sum(self.player.inventory.values())
- fast_print(f"Total Goods: {total_goods}")
- net_worth = self.player.money + sum(
- self.player.inventory.get(good, 0) * self.current_market.prices.get(good, 0) for good in ALL_GOODS
- )
- fast_print(f"Net Worth: ${net_worth}")
- # Calculate financial performance
- financial_performance = self.calculate_financial_performance(net_worth)
- # Calculate social performance
- social_performance = self.calculate_social_performance()
- # Display financial performance
- slow_print(f"\n{Fore.GREEN}Financial Performance:{Style.RESET_ALL}")
- fast_print(f" - Net Worth Score: {financial_performance['net_worth_score']} / 5")
- fast_print(f" - Liquidity Score: {financial_performance['liquidity_score']} / 5")
- financial_total = financial_performance['net_worth_score'] + financial_performance['liquidity_score']
- fast_print(f" - Total Financial Score: {financial_total} / 10")
- # Display social performance
- slow_print(f"\n{Fore.BLUE}Social Performance (Relationships):{Style.RESET_ALL}")
- fast_print(f" - Average Trade Relations Score: {social_performance['trade_score']} / 5")
- fast_print(f" - Average Reputation Score: {social_performance['reputation_score']} / 5")
- fast_print(f" - Average Favor Score: {social_performance['favor_score']} / 5")
- fast_print(f" - Relationship Status Influence Score: {social_performance['status_score']} / 5") # New Line
- social_total = social_performance['trade_score'] + social_performance['reputation_score'] + social_performance['favor_score'] + social_performance['status_score'] # Updated
- fast_print(f" - Total Social Score: {social_total} / 20") # Updated
- # Calculate total score
- total_score = financial_total + social_total
- max_total_score = 10 + 20 # Financial max + Social max
- # Determine final rating based on total_score
- rating = self.determine_rating(total_score)
- rating_message = self.generate_final_message(financial_total, social_total, rating)
- slow_print(f"\nFinal Rating: {Fore.CYAN}{rating}{Style.RESET_ALL}")
- slow_print(rating_message)
- # Display key events summary
- slow_print("\nSummary of Your Journey:")
- for event in self.key_events[:50]: # Limit to first 50 for readability
- fast_print(event)
- if len(self.key_events) > 50:
- fast_print("...")
- # Display Relationship Status Summary
- slow_print("\nRelationship Status Summary:")
- status_counts = {
- "Ally": 0,
- "Friendly": 0,
- "Neutral": 0,
- "Hostile": 0,
- "Enemy": 0
- }
- for town in self.player.visited_towns:
- status = self.player.get_overall_relationship_status(town)
- if status in status_counts:
- status_counts[status] += 1
- for status, count in status_counts.items():
- color = Fore.GREEN if status == "Ally" else Fore.BLUE if status == "Friendly" else Fore.YELLOW if status == "Neutral" else Fore.RED if status in ["Hostile", "Enemy"] else Fore.WHITE
- fast_print(f"{color}{status}: {count}{Style.RESET_ALL}")
- slow_print("\nThank you for playing the Text-Based Trading Game!")
- sys.exit()
- # Print methods for different speeds
- def fast_print(text):
- for char in text:
- print(char, end="", flush=True)
- time.sleep(0.0005)
- print()
- def medium_print(text):
- for char in text:
- print(char, end="", flush=True)
- time.sleep(0.005) # Medium typing speed
- print()
- def slow_print(text):
- for char in text:
- print(char, end="", flush=True)
- time.sleep(0.02) # Slow typing speed
- print()
- def get_relationship_status(score):
- """Converts a numerical relationship score into a descriptive status."""
- if score >= 20:
- return "Ally"
- elif score >= 10:
- return "Friendly"
- elif score >= 0:
- return "Neutral"
- elif score <= -20:
- return "Enemy"
- elif score <= -10:
- return "Hostile"
- else:
- return "Neutral" # For scores between -19 and -1
- # Main execution block with error handling
- if __name__ == "__main__":
- try:
- game_instance = Game()
- game_instance.start()
- except Exception as e:
- print(f"\n{Fore.RED}An unexpected error occurred: {e}{Style.RESET_ALL}")
- sys.exit(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement