AI improved

This commit is contained in:
Isaak Buslovich 2023-11-19 00:23:35 +01:00
parent 02b9ce142a
commit 5ff9f68404
Signed by: Isaak
GPG Key ID: EEC31D6437FBCC63

378
main.py
View File

@ -24,7 +24,6 @@ Note: Requires 'rich' and 'json' libraries for functionality.
import json import json
import random import random
from rich.console import Console from rich.console import Console
from rich.table import Table from rich.table import Table
from rich.prompt import Prompt from rich.prompt import Prompt
@ -38,8 +37,36 @@ crafting_recipes = {
} }
def main():
console = Console()
competitors_ids = ["Player", "RationalAI", "RiskTakingAI"]
market = Market()
# Initialise the player
player = Company("Player", [cid for cid in competitors_ids if cid != "Player"], market)
# Initialise AI competitors
rational_ai = AICompany("RationalAI", competitors_ids, market, risk_tolerance=0.3)
risk_taking_ai = AICompany("RiskTakingAI", competitors_ids, market, risk_tolerance=0.7)
ai_competitors = [rational_ai, risk_taking_ai]
market.companies = {company.player_id: company for company in ai_competitors + [player]}
# Game loop
for turn in range(1, 11):
console.print(f"\n--- Turn {turn} ---\n", style="grey50")
market.update_market()
for company in [player] + ai_competitors:
company.update_crafting()
company.make_decision(market, ai_competitors)
print_ai_actions(ai_competitors)
final_scores = market.calculate_final_scores()
display_final_scores(console, final_scores, market)
def load_json(filename): def load_json(filename):
"""Loads JSON data from a file."""
try: try:
with open(filename) as file: with open(filename) as file:
return json.load(file) return json.load(file)
@ -49,125 +76,82 @@ def load_json(filename):
class Market: class Market:
"""Manages market dynamics, including companies, products, stock transactions, and economic indicators."""
def __init__(self): def __init__(self):
self.current_turn = 0 self.current_turn = 0
self.companies = {} self.companies = {}
self.products = {'A': 10.0, 'B': 15.0, 'C': 20.0} self.products = {'A': 10.0, 'B': 15.0, 'C': 20.0}
self.starting_prices = self.products.copy()
self.events = load_json('market_events.json')["events"] self.events = load_json('market_events.json')["events"]
self.adjust_prices = lambda adjustment: {k: max(1, v + adjustment) for k, v in self.products.items()} self.adjust_prices = lambda adjustment: {k: max(1, v + adjustment) for k, v in self.products.items()}
self.event_effects = {"double": lambda x: x * 2, "halve": lambda x: x / 2, "increase": lambda x: x + 3.0, self.event_effects = {"double": lambda x: x * 2, "halve": lambda x: x / 2, "increase": lambda x: x + 3.0,
"decrease": lambda x: max(1, x - 3.0)} "decrease": lambda x: max(1, x - 3.0)}
self.stock_ledger = {} self.stock_ledger = {}
self.inflation_rate = 0.02
# Economic indicators self.unemployment_rate = 0.05
self.inflation_rate = 0.02 # Example starting inflation rate (2%) self.gdp = 500000
self.unemployment_rate = 0.05 # Example starting unemployment rate (5%)
self.gdp = 500000 # Example starting GDP value
def update_stock_ledger(self, company_id, owner_id, amount): def update_stock_ledger(self, company_id, owner_id, amount):
"""Updates the ledger with the given stock transaction details.""" self.stock_ledger[company_id, owner_id] = self.stock_ledger.get((company_id, owner_id), 0) + amount
key = (company_id, owner_id)
self.stock_ledger[key] = self.stock_ledger.get(key, 0) + amount
def get_stock_ownership(self, company_id, owner_id): def get_stock_ownership(self, company_id, owner_id):
"""Retrieves stock ownership details for a specified company and owner."""
return self.stock_ledger.get((company_id, owner_id), 0) return self.stock_ledger.get((company_id, owner_id), 0)
def get_stock_price(self, company_id): def get_stock_price(self, company_id):
"""Returns the current stock price of the specified company.""" return round(self.companies[company_id].value / 100.0, 2)
company = self.companies[company_id]
company_value = company.value # No argument passed
return round(company_value / 100.0, 2)
def update_market(self): def update_market(self):
"""Applies market events, adjusts prices, and updates economic indicators for the current turn."""
self.current_turn += 1 self.current_turn += 1
trend_adjustment = random.choice([2, -2, 0]) trend_adjustment = random.choice([2, -2, 0])
self.products = self.adjust_prices(trend_adjustment) self.products = self.adjust_prices(trend_adjustment)
event = random.choices(self.events, weights=[e["probability"] for e in self.events])[0] event = random.choices(self.events, weights=[e["probability"] for e in self.events])[0]
if event["effect"] in ["new_competitor", "exit_competitor"]: if event["effect"] in ["new_competitor", "exit_competitor"]:
self.handle_competitor_event(event["effect"]) self.handle_competitor_event(event["effect"])
else: else:
self.products = {k: self.event_effects[event["effect"]](v) for k, v in self.products.items()} self.products = {k: self.event_effects[event["effect"]](v) for k, v in self.products.items()}
self.update_economic_indicators() self.update_economic_indicators()
def adjust_prices(self): def adjust_prices(self):
"""Adjusts market product prices based on inflation and other factors."""
for product, price in self.products.items(): for product, price in self.products.items():
inflation_adjustment = price * self.inflation_rate inflation_adjustment = price * self.inflation_rate
new_price = price + inflation_adjustment
# small random fluctuation for realism
fluctuation = random.uniform(-0.03, 0.03) fluctuation = random.uniform(-0.03, 0.03)
new_price += fluctuation self.products[product] = round(max(1.5, price + inflation_adjustment + fluctuation), 2)
new_price = max(1.5, new_price)
self.products[product] = round(new_price, 2)
return self.products return self.products
def handle_competitor_event(self, effect): def handle_competitor_event(self, effect):
"""Handles market changes due to new or exiting competitors."""
adjustment = float(random.randint(1, 3)) adjustment = float(random.randint(1, 3))
self.products = {k: max(1.0, v - adjustment) if effect == "new_competitor" else v + adjustment for k, v in self.products = {k: max(1.0, v - adjustment) if effect == "new_competitor" else v + adjustment for k, v in
self.products.items()} self.products.items()}
def update_economic_indicators(self): def update_economic_indicators(self):
"""Updates market's economic indicators like inflation and unemployment rates.""" self.inflation_rate = max(0.5, self.inflation_rate + random.uniform(-0.01, 0.01))
# Update the inflation rate based on market conditions self.unemployment_rate = min(max(self.unemployment_rate + random.uniform(-0.005, 0.005), 0), 1)
self.inflation_rate += random.uniform(-0.01, 0.01) # Random fluctuation
self.inflation_rate = max(0.5, self.inflation_rate) # Ensure non-negative
# Update the unemployment rate
self.unemployment_rate += random.uniform(-0.005, 0.005) # Random fluctuation
self.unemployment_rate = min(max(self.unemployment_rate, 0), 1) # Bound between 0 and 1
# Update GDP based on market performance
self.gdp += self.gdp * (random.uniform(-0.01, 0.03) + self.inflation_rate) self.gdp += self.gdp * (random.uniform(-0.01, 0.03) + self.inflation_rate)
def calculate_final_scores(self): def calculate_final_scores(self):
"""Calculates and returns final scores based on company values and stock ownership."""
final_scores = {} final_scores = {}
for company_id, company in self.companies.items(): for company_id, company in self.companies.items():
# Use the 'value' property instead of the 'get_value' method
final_score = company.value final_score = company.value
# Determine the majority owner
majority_owner = max(company.own_stock_ownership, majority_owner = max(company.own_stock_ownership,
key=lambda owner: (company.own_stock_ownership[owner], owner)) key=lambda owner: (company.own_stock_ownership[owner], owner))
majority_percentage = company.own_stock_ownership[majority_owner] majority_percentage = company.own_stock_ownership[majority_owner]
# Check if the majority owner owns 51% or more
is_major_owner = majority_percentage >= 51 is_major_owner = majority_percentage >= 51
# Initialize or update the score
if company_id not in final_scores: if company_id not in final_scores:
final_scores[company_id] = {'score': 0, 'note': '', 'majority_owner': majority_owner} final_scores[company_id] = {'score': 0, 'note': '', 'majority_owner': majority_owner}
# Distribute scores
for owner_id, percentage in company.own_stock_ownership.items(): for owner_id, percentage in company.own_stock_ownership.items():
if percentage > 20: if percentage > 20:
score_transfer = final_score * (percentage / 100) final_scores[owner_id] = final_scores.get(owner_id, {'score': 0, 'note': '', 'majority_owner': ''})
if owner_id not in final_scores: final_scores[owner_id]['score'] += final_score * (percentage / 100)
final_scores[owner_id] = {'score': 0, 'note': '', 'majority_owner': ''}
final_scores[owner_id]['score'] += score_transfer
# If no one owns 51% or more, assign the remainder to the company itself
if not is_major_owner: if not is_major_owner:
remaining_score = final_score - sum( remaining_score = final_score - sum(
final_scores.get(owner, {'score': 0})['score'] for owner in company.own_stock_ownership) final_scores.get(owner, {'score': 0})['score'] for owner in company.own_stock_ownership)
final_scores[company_id]['score'] += remaining_score final_scores[company_id]['score'] += remaining_score
return final_scores return final_scores
class Company: class Company:
"""Represents a company within the market, managing finances, inventory, and stock transactions.""" """Represents a company within the market, managing finances, inventory, and stock transactions."""
def __init__(self, player_id, competitors_ids, market=None):
def __init__(self, player_id, competitors_ids, market=None, debug=False):
self.player_id = player_id self.player_id = player_id
self.cash = 500.0 self.cash = 500.0
self.inventory = {'A': 0, 'B': 0, 'C': 0} self.inventory = {'A': 0, 'B': 0, 'C': 0}
@ -176,6 +160,7 @@ class Company:
self.stock_holdings = {cid: 0 for cid in set([player_id] + competitors_ids + ["RationalAI", "RiskTakingAI"])} self.stock_holdings = {cid: 0 for cid in set([player_id] + competitors_ids + ["RationalAI", "RiskTakingAI"])}
self.total_shares = 100 self.total_shares = 100
self._market = market self._market = market
self._debug = debug
@property @property
def value(self): def value(self):
@ -184,6 +169,7 @@ class Company:
def craft_product(self, recipe_key): def craft_product(self, recipe_key):
"""Processes crafting of a product based on the chosen recipe.""" """Processes crafting of a product based on the chosen recipe."""
if self._debug:
print(f"Inventory before crafting: {self.inventory}") print(f"Inventory before crafting: {self.inventory}")
recipe = crafting_recipes[recipe_key] recipe = crafting_recipes[recipe_key]
if all(self.inventory[product] >= quantity for product, quantity in recipe['input'].items()): if all(self.inventory[product] >= quantity for product, quantity in recipe['input'].items()):
@ -192,33 +178,41 @@ class Company:
print("Crafting order placed.") print("Crafting order placed.")
else: else:
print("Not enough resources to craft.") print("Not enough resources to craft.")
if self._debug:
print(f"Inventory after crafting: {self.inventory}") print(f"Inventory after crafting: {self.inventory}")
def _update_inventory(self, items, decrease=False): def _update_inventory(self, items, decrease=False):
"""Updates the inventory based on the given items.""" """Updates the inventory based on the given items."""
if self._debug:
print(f"Inventory before update: {self.inventory}") print(f"Inventory before update: {self.inventory}")
for product, quantity in items.items(): for product, quantity in items.items():
if decrease: if decrease:
self.inventory[product] -= quantity self.inventory[product] -= quantity
else: else:
self.inventory[product] += quantity self.inventory[product] += quantity
if self._debug:
print(f"Inventory after update: {self.inventory}") print(f"Inventory after update: {self.inventory}")
def update_crafting(self): def update_crafting(self):
"""Updates the crafting queue, completing orders as their turns conclude.""" """Updates the crafting queue, completing orders as their turns conclude."""
if self._debug:
print(f"Crafting queue before update: {self.crafting_queue}") print(f"Crafting queue before update: {self.crafting_queue}")
completed_orders = [] completed_orders = []
for order in self.crafting_queue: for order in self.crafting_queue:
if self._debug:
print(f"Processing order: {order}") print(f"Processing order: {order}")
order['turns_remaining'] -= 1 order['turns_remaining'] -= 1
if order['turns_remaining'] == 0: if order['turns_remaining'] == 0:
if self._debug:
print(f"Completing order: {order}") print(f"Completing order: {order}")
self._update_inventory(order['recipe']['output'], decrease=False) self._update_inventory(order['recipe']['output'])
if self._debug:
print(f"Inventory after completing order: {self.inventory}") print(f"Inventory after completing order: {self.inventory}")
completed_orders.append(order) completed_orders.append(order)
for order in completed_orders: for order in completed_orders:
self.crafting_queue.remove(order) self.crafting_queue.remove(order)
if self._debug:
print(f"Crafting queue after update: {self.crafting_queue}") print(f"Crafting queue after update: {self.crafting_queue}")
def trade_product(self, market, product, quantity, buying=True): def trade_product(self, market, product, quantity, buying=True):
@ -265,33 +259,34 @@ class Company:
if self.cash < total_value: if self.cash < total_value:
return "Insufficient funds to buy stocks." return "Insufficient funds to buy stocks."
self._update_stock_ownership(company_id, amount, total_value, buying=True) # Update stock ownership
message = f"Bought {amount} stocks of {company_id}."
if is_ai: if is_ai:
self.last_action = message self.stock_holdings[company_id] += amount # Increase AI's stock holdings
else: else:
print(message) self.own_stock_ownership[company_id] += amount # Increase player's own stock holdings
return message
self.cash -= total_value # Deduct the cost from the buyer's cash
return f"Bought {amount} stocks of {company_id}."
def _sell_stock(self, company_id, amount, total_value, is_ai): def _sell_stock(self, company_id, amount, total_value, is_ai):
"""Handles the selling of stocks for the specified company.""" """Handles the selling of stocks for the specified company."""
# Check if the seller has enough stocks to sell
if self._get_stock_ownership(company_id) < amount: if self._get_stock_ownership(company_id) < amount:
return "Not enough stocks to sell." return "Not enough stocks to sell."
self._update_stock_ownership(company_id, amount, total_value, buying=False) # Update stock ownership
message = f"Sold {amount} stocks of {company_id}."
if is_ai: if is_ai:
self.last_action = message self.stock_holdings[company_id] -= amount # Decrease AI's stock holdings
else: else:
print(message) self.own_stock_ownership[company_id] -= amount # Decrease player's own stock holdings
return message
self.cash += total_value # Add the proceeds to the seller's cash
return f"Sold {amount} stocks of {company_id}."
def _calculate_available_shares(self, company_id): def _calculate_available_shares(self, company_id):
"""Calculates the number of available shares for a given company.""" """Calculates the number of available shares for a given company."""
if company_id == self.player_id: total_owned = sum(self.stock_holdings.values()) + sum(self.own_stock_ownership.values())
return self.total_shares - sum(self.own_stock_ownership.values()) + self.own_stock_ownership[self.player_id] return self.total_shares - total_owned
else:
return self.total_shares - self.stock_holdings.get(company_id, 0)
def _get_stock_ownership(self, company_id): def _get_stock_ownership(self, company_id):
"""Retrieves the stock ownership amount for a given company.""" """Retrieves the stock ownership amount for a given company."""
@ -316,12 +311,12 @@ class Company:
def make_decision(self, market, competitors): def make_decision(self, market, competitors):
"""Presents decision options to the user and processes the chosen action.""" """Presents decision options to the user and processes the chosen action."""
console = Console() console = Console()
status_table = Table(title=f"[bold green]{self.player_id}'s Turn - Turn {market.current_turn}", box=box.ROUNDED) status_table = Table(title=f"[bold cyan]{self.player_id}'s Turn - Turn {market.current_turn}", box=box.ROUNDED)
status_table.add_column("Category", style="bold cyan") status_table.add_column("Category", style="bold cyan")
status_table.add_column("Details") status_table.add_column("Details")
status_table.add_row("Cash", f"[bold yellow]{self.cash:.2f}") status_table.add_row("Cash", f"[bold blue]{self.cash:.2f}")
status_table.add_row("Inventory", ', '.join( status_table.add_row("Inventory", ', '.join(
[f"[bold magenta]{item}: {quantity}" for item, quantity in self.inventory.items()])) [f"[bold]{item}: {quantity}" for item, quantity in self.inventory.items()]))
status_table.add_row("Market Prices", ', '.join( status_table.add_row("Market Prices", ', '.join(
[f"[bold blue]{product}: {price:.2f}" for product, price in market.products.items()])) [f"[bold blue]{product}: {price:.2f}" for product, price in market.products.items()]))
shareholders = ', '.join( shareholders = ', '.join(
@ -341,7 +336,7 @@ class Company:
choices_display = "\n".join([f"{key}: {value}" for key, value in actions.items()]) choices_display = "\n".join([f"{key}: {value}" for key, value in actions.items()])
console.print(f"Available Actions:\n{choices_display}", style="bold") console.print(f"Available Actions:\n{choices_display}", style="bold")
action_choice = Prompt.ask("Choose your action", choices=list(actions.keys()), default="4") action_choice = Prompt.ask("Choose your action", default="4")
selected_action = actions.get(action_choice, None) selected_action = actions.get(action_choice, None)
if selected_action == "Trade Products": if selected_action == "Trade Products":
@ -427,186 +422,113 @@ class Company:
return all(price > 20 for price in self._market.products.values()) return all(price > 20 for price in self._market.products.values())
def is_market_bust(market):
return all(price < 0.75 * market.starting_prices[product] for product, price in market.products.items())
class AICompany(Company): class AICompany(Company):
"""Represents an AI-driven company with automated trading, crafting, and stock actions.""" def __init__(self, player_id, competitors_ids, market, risk_tolerance):
def __init__(self, player_id, competitors_ids, market):
super().__init__(player_id, competitors_ids, market) super().__init__(player_id, competitors_ids, market)
self.last_action = "None" self.risk_tolerance = risk_tolerance
self.actions_history = []
self.average_prices = {product: market.products[product] for product in market.products} self.average_prices = {product: market.products[product] for product in market.products}
def update_average_prices(self): def update_average_prices(self):
"""Updates the average prices of products based on the current market turn.""" self.average_prices = {product: (self.average_prices[product] * (self._market.current_turn - 1) + price) / self._market.current_turn
turn = self._market.current_turn for product, price in self._market.products.items()}
for product, price in self._market.products.items():
self.average_prices[product] = (self.average_prices[product] * (turn - 1) + price) / turn
def choose_best_crafting_option(self): def make_decision(self, market, competitors):
"""Selects the most viable crafting option based on current inventory.""" if self.risk_tolerance > 0.5: # High-Risk AI
return next((recipe_key for recipe_key, recipe in crafting_recipes.items() self.high_risk_decision(market, competitors)
if all(self.inventory[prod] >= qty for prod, qty in recipe['input'].items())), None) else: # Low-Risk AI
self.low_risk_decision(market, competitors)
def perform_trade_action(self, action): def low_risk_decision(self, market, competitors):
"""Performs a trade action, either buying or selling, based on the specified action.""" if market.current_turn == 1:
if action == 'sell': self.buy_product('A', self.cash / 3)
self.sell_inventory_items() elif market.current_turn == 2:
elif action == 'buy': self.buy_product('B', min(self.inventory['A'], self.cash / market.products['B']))
self.buy_inventory_items() elif market.current_turn >= 3:
self.buy_and_craft(market)
def sell_inventory_items(self): def high_risk_decision(self, market, competitors):
"""Executes the selling of inventory items.""" if market.current_turn == 1:
for product, quantity in self.inventory.items(): self.sell_own_shares(market)
if quantity > 0: self.buy_product('A', self.cash / 2)
self.trade_product(self._market, product, quantity, buying=False) self.buy_product('B', self.cash)
self.last_action = f"Sold {quantity} of {product}" else:
break if self.should_craft(market):
self.buy_and_craft(market)
if self.should_sell_products(market):
self.sell_high_value_products(market)
def buy_inventory_items(self): def buy_product(self, product, budget):
"""Executes the buying of inventory items based on current market prices.""" quantity = int(budget // self._market.products[product])
for product, price in self._market.products.items():
if price > 0:
quantity = int(self.cash // price)
if quantity > 0: if quantity > 0:
self.trade_product(self._market, product, quantity) self.trade_product(self._market, product, quantity)
self.last_action = f"Bought {quantity} of {product}" action = f"Bought {quantity} of {product}"
break self.actions_history.append(action)
def perform_stock_action(self, action): def sell_own_shares(self, market):
"""Performs a stock action, buying or selling, based on a selected strategy.""" amount_to_sell = int(self.own_stock_ownership[self.player_id] * 0.25) # Sell 25% of own shares
company_id, amount = self.select_stock_action(action) if amount_to_sell > 0:
if company_id: self.trade_stock('sell', market, self.player_id, amount_to_sell, is_ai=True)
self.trade_stock(action, self._market, company_id, amount, is_ai=True) action = f"Sold {amount_to_sell} of own shares"
self.actions_history.append(action)
def select_stock_action(self, action): def should_craft(self, market):
"""Selects a stock action to perform, either buying or selling.""" return all(self.inventory[product] >= qty for product, qty in crafting_recipes['recipe2']['input'].items())
if action == 'buy':
return self.select_stock_to_buy()
elif action == 'sell':
return self.select_stock_to_sell()
return None, 0
def select_stock_to_buy(self): def should_sell_products(self, market):
"""Chooses a company's stock to buy based on market conditions.""" return any(market.products[product] >= 2 * self.average_prices[product] for product in self.inventory if self.inventory[product] > 0)
company_id = random.choice(list(self._market.companies.keys()))
amount = random.randint(1, 10)
return company_id, amount
def select_stock_to_sell(self): def sell_high_value_products(self, market):
"""Chooses a company's stock to sell from the AI's holdings.""" for product, quantity in self.inventory.items():
owned_stocks = [(comp_id, amount) for comp_id, amount in self.stock_holdings.items() if amount > 0] if quantity > 0 and market.products[product] >= 2 * self.average_prices[product]:
if owned_stocks: self.trade_product(market, product, quantity, buying=False)
company_id, _ = random.choice(owned_stocks) action = f"Sold high value products"
amount = random.randint(1, self.stock_holdings[company_id]) self.actions_history.append(action)
return company_id, amount
return None, 0
def attempt_crafting(self): def buy_and_craft(self, market):
"""Attempts to craft an item based on the best available crafting option.""" chosen_recipe = crafting_recipes['recipe2']
recipe_key = self.choose_best_crafting_option() if all(self.inventory[product] >= qty for product, qty in chosen_recipe['input'].items()):
if recipe_key: self.craft_product('recipe2')
self.craft_product(recipe_key) print(f"Crafting using recipe2")
self.last_action = f"Started crafting {recipe_key}" action = "Crafted products using recipe2"
self.actions_history.append(action)
class RationalAI(AICompany):
"""AI strategy focused on rational and market-condition-based decisions."""
def __init__(self, player_id, competitors_ids, market):
super().__init__(player_id, competitors_ids, market)
def make_decision(self, market, competitors):
"""Makes a market decision based on current market conditions and AI strategy."""
if self.should_craft():
self.attempt_crafting()
elif self.is_market_boom() or market.current_turn > 7:
self.perform_trade_action('sell')
else: else:
self.perform_trade_action('buy') print("Not enough resources to craft using recipe2")
self.perform_stock_action(random.choice(['buy', 'sell']))
def should_craft(self):
"""Determines if crafting is a rational choice based on market conditions."""
return random.choice([True, False]) if self.is_market_boom() else self._market.current_turn <= 7
class RiskTakingAI(AICompany):
"""AI strategy focused on high-risk, high-reward decisions in the market."""
def __init__(self, player_id, competitors_ids, market):
super().__init__(player_id, competitors_ids, market)
def make_decision(self, market, competitors):
"""Makes bold market decisions based on a high-risk approach."""
if random.choice([True, False]):
self.perform_trade_action('buy')
elif self.should_craft():
self.attempt_crafting()
else:
self.perform_trade_action('sell')
self.perform_stock_action(random.choice(['buy', 'sell']))
def should_craft(self):
"""Determines if crafting is a suitable choice, leaning towards riskier decisions."""
return random.choice([True, False]) if self.is_market_boom() else self._market.current_turn <= 7
def print_ai_actions(ai_competitors): def print_ai_actions(ai_competitors):
"""Displays the last actions taken by AI competitors in a styled console format.""" """Displays the actions history, current cash, and inventory of AI competitors."""
console = Console() console = Console()
for ai in ai_competitors: for ai in ai_competitors:
action_text = Text() panel_text = Text()
inventory_text = ', '.join([f"{product}: {quantity}" for product, quantity in ai.inventory.items()])
if "Bought" in ai.last_action or "Sold" in ai.last_action: # List all actions
action_color = "green" if "Bought" in ai.last_action else "red" for idx, action in enumerate(ai.actions_history, 1):
action_text.append(ai.last_action, style=f"bold {action_color}") panel_text.append(f"{idx}. Action: {action}\n", style="bold cyan")
elif "Crafting" in ai.last_action:
action_text.append(ai.last_action, style="bold blue")
else:
action_text.append(ai.last_action, style="bold")
console.print( # Append current cash and inventory to the text
Panel(action_text, title=f"[bold]{ai.player_id}'s Action", border_style="bright_yellow")) panel_text.append(f"\nCurrent Cash: {ai.cash:.2f}\n", style="bold yellow")
panel_text.append(f"Inventory: {inventory_text}", style="bold magenta")
# Display in a panel
console.print(Panel(panel_text, title=f"[bold]{ai.player_id}'s Status", border_style="grey50"))
def main():
"""
Simulates a 10-turn market game between the player and two AI competitors.
"""
competitors_ids = ["Player", "RationalAI", "RiskTakingAI"] def display_final_scores(console, final_scores, market):
market = Market() """Displays the final scores in a styled table."""
player = Company("Player", [company_type for company_type in competitors_ids if company_type != "Player"], market) score_table = Table(header_style="bold cyan", box=box.DOUBLE_EDGE)
score_table.add_column("Company", style="bold")
other_competitors = set(competitors_ids) - {"RationalAI", "RiskTakingAI"} score_table.add_column("Final Score", justify="right")
ai_competitors = [ score_table.add_column("Majority Owner", style="bold")
RationalAI("RationalAI", list(other_competitors), market),
RiskTakingAI("RiskTakingAI", list(other_competitors), market),
]
market.companies = {"Player": player, "RationalAI": ai_competitors[0], "RiskTakingAI": ai_competitors[1]}
for turn in range(10):
print(f"\n---\n")
market.update_market()
player.update_crafting()
player.make_decision(market, ai_competitors)
print(f"\n---\n")
for ai in ai_competitors:
ai.make_decision(market, ai_competitors)
ai.update_crafting()
print_ai_actions(ai_competitors)
print(f"\n---\n")
final_scores = market.calculate_final_scores()
console = Console()
score_table = Table(header_style="bold magenta", box=box.DOUBLE_EDGE)
score_table.add_column("Company", style="bold cyan")
score_table.add_column("Final Score", justify="right", style="bold yellow")
score_table.add_column("Majority Owner", style="bold green")
score_table.add_column("Ownership Percentage", justify="right", style="dim") score_table.add_column("Ownership Percentage", justify="right", style="dim")
sorted_scores = sorted(final_scores.items(), key=lambda item: item[1]['score'], reverse=True)
for company_id, data in sorted_scores: for company_id, data in sorted(final_scores.items(), key=lambda item: item[1]['score'], reverse=True):
ownership_percentage = f"{data['score'] / market.companies[company_id].value * 100:.2f}%" ownership_percentage = f"{data['score'] / market.companies[company_id].value * 100:.2f}%"
score_table.add_row(company_id, f"{data['score']:.0f}", data['majority_owner'], ownership_percentage) score_table.add_row(company_id, f"{data['score']:.0f}", data['majority_owner'], ownership_percentage)