Market Events and Indicators fixed

This commit is contained in:
Isaak Buslovich 2023-11-19 23:34:47 +01:00
parent df744a2410
commit 82b89a7045
Signed by: Isaak
GPG Key ID: EEC31D6437FBCC63

102
main.py
View File

@ -15,7 +15,9 @@ from rich.text import Text
crafting_recipes = { crafting_recipes = {
'Industrial Synthesis': {'input': {'Coal': 4, 'Copper': 4}, 'output': {'Conductor': 10}, 'turns': 3}, 'Industrial Synthesis': {'input': {'Coal': 4, 'Copper': 4}, 'output': {'Conductor': 10}, 'turns': 3},
'Manual Synthesis': {'input': {'Coal': 1, 'Copper': 1}, 'output': {'Conductor': 2}, 'turns': 2} 'Manual Synthesis': {'input': {'Coal': 1, 'Copper': 1}, 'output': {'Conductor': 2}, 'turns': 2},
'Microchip Fabrication': {'input': {'Silicon': 2, 'Conductor': 1}, 'output': {'Microchips': 5}, 'turns': 4},
'Battery Production': {'input': {'Lithium': 3, 'Copper': 2}, 'output': {'Batteries': 4}, 'turns': 3}
} }
@ -37,6 +39,9 @@ def main():
# Game loop # Game loop
for turn in range(1, 27): for turn in range(1, 27):
console.print(f"\n--- Turn {turn} ---\n", style="grey50") console.print(f"\n--- Turn {turn} ---\n", style="grey50")
market.inflation_rate += market.inflation_change if market.inflation_growing else -market.inflation_change
market.inflation_rate = max(0.0001, min(market.inflation_rate, 0.05))
market.gdp *= (1 + (market.inflation_rate / 20))
market.update_market() market.update_market()
market.print_market_events() market.print_market_events()
@ -83,7 +88,10 @@ class Market:
def __init__(self): def __init__(self):
self.current_turn = 0 self.current_turn = 0
self.companies = {} self.companies = {}
self.products = {'Coal': 10.0, 'Copper': 15.0, 'Conductor': 20.0} self.products = {
'Coal': 10.0, 'Copper': 15.0, 'Conductor': 20.0,
'Silicon': 12.0, 'Lithium': 18.0, 'Microchips': 30.0, 'Batteries': 25.0
}
self.starting_prices = self.products.copy() self.starting_prices = self.products.copy()
self.events = load_json('market_events.json')["events"] self.events = load_json('market_events.json')["events"]
self.stock_ledger = {} self.stock_ledger = {}
@ -102,16 +110,48 @@ class Market:
def update_market(self): def update_market(self):
self.current_turn += 1 self.current_turn += 1
self.previous_prices = self.products.copy() self.previous_prices = self.products.copy()
self.update_prices()
# Update prices based on inflation and random fluctuations
for product in self.products:
inflation_adjustment = self.inflation_rate
random_fluctuation = random.uniform(-0.01, 0.01) # ±1% fluctuation
price_change_factor = 1 + inflation_adjustment + random_fluctuation
self.products[product] *= price_change_factor
self.reset_trade_volumes()
# Procedural generation of market trends
self.trend_factor = self.generate_market_trend()
# Update economic indicators
self.update_economic_indicators()
# Handle market events
self.handle_market_events()
def update_prices(self):
min_prices = {
'Coal': 0.01, 'Copper': 0.20, 'Conductor': 1.50,
'Silicon': 0.50, 'Lithium': 0.50, 'Microchips': 2.00, 'Batteries': 5.00
}
max_change = 0.1
for product in self.products:
inflation_adjustment = self.inflation_rate
random_fluctuation = random.uniform(-max_change, max_change)
price_change_factor = 1 + inflation_adjustment + random_fluctuation
new_price = self.products[product] * price_change_factor
self.products[product] = max(min_prices[product], new_price)
self.reset_trade_volumes() self.reset_trade_volumes()
self.trend_factor = self.generate_market_trend() self.trend_factor = self.generate_market_trend()
self.update_economic_indicators() self.update_economic_indicators()
self.handle_market_events() self.handle_market_events()
def calculate_price_change(self, product):
def update_prices(self): demand_factor = self.total_bought[product] - self.total_sold[product]
for product in self.products: # Here you can define how strongly demand affects the price, e.g., 0.05 as in your original code
demand_factor = self.total_bought[product] - self.total_sold[product] return demand_factor * 0.05
self.products[product] *= (1 + demand_factor * 0.05)
def reset_trade_volumes(self): def reset_trade_volumes(self):
self.total_bought = dict.fromkeys(self.total_bought, 0) self.total_bought = dict.fromkeys(self.total_bought, 0)
@ -184,8 +224,8 @@ class Market:
console = Console() console = Console()
event_info = f"Last Market Event: {self.last_event_name}\n" event_info = f"Last Market Event: {self.last_event_name}\n"
economic_indicators = ( economic_indicators = (
f"Inflation Rate: {self.inflation_rate:.2f}%\n" f"Inflation Rate: {self.inflation_rate * 100:.2f}%\n"
f"Unemployment Rate: {self.unemployment_rate:.2f}%\n" f"Unemployment Rate: {self.unemployment_rate * 100:.2f}%\n"
f"GDP: {self.gdp:.2f}" f"GDP: {self.gdp:.2f}"
) )
@ -315,10 +355,12 @@ class Company:
_market (Market): Reference to the game's market. _market (Market): Reference to the game's market.
_debug (bool): Flag for enabling debug mode. _debug (bool): Flag for enabling debug mode.
""" """
def __init__(self, player_id, competitors_ids, market=None, debug=False): 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 = {'Coal': 0, 'Copper': 0, 'Conductor': 0} self.inventory = {'Coal': 0, 'Copper': 0, 'Conductor': 0,
'Silicon': 0, 'Lithium': 0, 'Microchips': 0, 'Batteries': 0}
self.crafting_queue = [] self.crafting_queue = []
self.own_stock_ownership = {cid: 51 if cid == player_id else 0 for cid in [player_id] + competitors_ids} self.own_stock_ownership = {cid: 51 if cid == player_id else 0 for cid in [player_id] + competitors_ids}
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"])}
@ -399,6 +441,9 @@ class Company:
else: else:
print("Insufficient inventory to complete sale.") print("Insufficient inventory to complete sale.")
# Update market prices after trading
market.update_prices() # This call ensures prices are updated with constraints
def crafting_decision(self): def crafting_decision(self):
"""Displays crafting options and handles the user's crafting choice.""" """Displays crafting options and handles the user's crafting choice."""
print("\nCrafting Decision") print("\nCrafting Decision")
@ -452,14 +497,21 @@ class Company:
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 # Check if the seller has enough stocks to sell
if self._get_stock_ownership(company_id) < amount: stock_ownership = self._get_stock_ownership(company_id) if not is_ai else self.own_stock_ownership[company_id]
if stock_ownership < amount:
return "Not enough stocks to sell." return "Not enough stocks to sell."
# Update stock ownership # Update stock ownership
if is_ai: if is_ai:
self.stock_holdings[company_id] -= amount # Decrease AI's stock holdings if company_id == self.player_id:
# AI selling its own stock
self.own_stock_ownership[company_id] -= amount
else:
# AI selling other company's stock
self.stock_holdings[company_id] -= amount
else: else:
self.own_stock_ownership[company_id] -= amount # Decrease player's own stock holdings # Player selling stock
self.own_stock_ownership[company_id] -= amount
self.cash += total_value # Add the proceeds to the seller's cash self.cash += total_value # Add the proceeds to the seller's cash
return f"Sold {amount} stocks of {company_id}." return f"Sold {amount} stocks of {company_id}."
@ -491,7 +543,8 @@ class Company:
def make_decision(self, market, competitors): def make_decision(self, market, competitors):
console = Console() console = Console()
status_table = Table(title=f"\n[bold cyan]{self.player_id}'s Turn - Turn {market.current_turn}", box=box.ROUNDED) status_table = Table(title=f"\n[bold cyan]{self.player_id}'s Turn - Turn {market.current_turn}",
box=box.ROUNDED)
# Cash Row # Cash Row
status_table.add_column("Category", style="bold cyan") status_table.add_column("Category", style="bold cyan")
@ -635,6 +688,7 @@ class AICompany(Company):
Methods provide the AI's logic for crafting, trading, stock transactions, and handling market events. Methods provide the AI's logic for crafting, trading, stock transactions, and handling market events.
""" """
def __init__(self, player_id, competitors_ids, market, risk_tolerance): def __init__(self, player_id, competitors_ids, market, risk_tolerance):
super().__init__(player_id, competitors_ids, market) super().__init__(player_id, competitors_ids, market)
self.risk_tolerance = risk_tolerance self.risk_tolerance = risk_tolerance
@ -644,7 +698,7 @@ class AICompany(Company):
def update_average_prices(self): def update_average_prices(self):
"""Updates the average prices of products in the market for AI decision-making purposes.""" """Updates the average prices of products in the market for AI decision-making purposes."""
self.average_prices = {product: (self.average_prices[product] * ( self.average_prices = {product: (self.average_prices[product] * (
self._market.current_turn - 1) + price) / self._market.current_turn self._market.current_turn - 1) + price) / self._market.current_turn
for product, price in self._market.products.items()} for product, price in self._market.products.items()}
def make_decision(self, market, competitors): def make_decision(self, market, competitors):
@ -724,7 +778,8 @@ class AICompany(Company):
""" """
Determines if the AI should craft products based on inventory and market conditions. Determines if the AI should craft products based on inventory and market conditions.
""" """
return all(self.inventory[product] >= qty for product, qty in crafting_recipes['Manual Synthesis']['input'].items()) return all(
self.inventory[product] >= qty for product, qty in crafting_recipes['Manual Synthesis']['input'].items())
def should_sell_products(self, market): def should_sell_products(self, market):
""" """
@ -758,7 +813,7 @@ class AICompany(Company):
def print_ai_actions(ai_competitors): def print_ai_actions(ai_competitors):
"""Displays the actions history, current cash, and inventory of AI competitors.""" """Displays the actions history, current cash, inventory, and stock information of AI competitors."""
console = Console() console = Console()
for ai in ai_competitors: for ai in ai_competitors:
panel_text = Text() panel_text = Text()
@ -770,7 +825,16 @@ def print_ai_actions(ai_competitors):
# Append current cash and inventory to the text # Append current cash and inventory to the text
panel_text.append(f"\nCurrent Cash: {ai.cash:.2f}\n", style="bold blue") panel_text.append(f"\nCurrent Cash: {ai.cash:.2f}\n", style="bold blue")
panel_text.append(f"Inventory: {inventory_text}", style="bold cyan") panel_text.append(f"Inventory: {inventory_text}\n", style="bold cyan")
# Display Shareholders and Investments
shareholders_text = ', '.join(
[f"{company}: {ownership} shares" for company, ownership in ai.own_stock_ownership.items()])
investments_text = ', '.join(
[f"{company}: {holding} shares" for company, holding in ai.stock_holdings.items() if holding > 0])
panel_text.append(f"Shareholders: {shareholders_text}\n", style="bold green")
panel_text.append(f"Investments: {investments_text}", style="bold magenta")
# Display in a panel # Display in a panel
console.print(Panel(panel_text, title=f"[bold]{ai.player_id}'s Status", border_style="grey50")) console.print(Panel(panel_text, title=f"[bold]{ai.player_id}'s Status", border_style="grey50"))