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

98
main.py
View File

@ -15,7 +15,9 @@ from rich.text import Text
crafting_recipes = {
'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
for turn in range(1, 27):
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.print_market_events()
@ -83,7 +88,10 @@ class Market:
def __init__(self):
self.current_turn = 0
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.events = load_json('market_events.json')["events"]
self.stock_ledger = {}
@ -102,16 +110,48 @@ class Market:
def update_market(self):
self.current_turn += 1
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.trend_factor = self.generate_market_trend()
self.update_economic_indicators()
self.handle_market_events()
def update_prices(self):
for product in self.products:
def calculate_price_change(self, product):
demand_factor = self.total_bought[product] - self.total_sold[product]
self.products[product] *= (1 + demand_factor * 0.05)
# Here you can define how strongly demand affects the price, e.g., 0.05 as in your original code
return demand_factor * 0.05
def reset_trade_volumes(self):
self.total_bought = dict.fromkeys(self.total_bought, 0)
@ -184,8 +224,8 @@ class Market:
console = Console()
event_info = f"Last Market Event: {self.last_event_name}\n"
economic_indicators = (
f"Inflation Rate: {self.inflation_rate:.2f}%\n"
f"Unemployment Rate: {self.unemployment_rate:.2f}%\n"
f"Inflation Rate: {self.inflation_rate * 100:.2f}%\n"
f"Unemployment Rate: {self.unemployment_rate * 100:.2f}%\n"
f"GDP: {self.gdp:.2f}"
)
@ -315,10 +355,12 @@ class Company:
_market (Market): Reference to the game's market.
_debug (bool): Flag for enabling debug mode.
"""
def __init__(self, player_id, competitors_ids, market=None, debug=False):
self.player_id = player_id
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.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"])}
@ -399,6 +441,9 @@ class Company:
else:
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):
"""Displays crafting options and handles the user's crafting choice."""
print("\nCrafting Decision")
@ -452,14 +497,21 @@ class Company:
def _sell_stock(self, company_id, amount, total_value, is_ai):
"""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:
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."
# Update stock ownership
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:
self.own_stock_ownership[company_id] -= amount # Decrease player's own stock holdings
# AI selling other company's stock
self.stock_holdings[company_id] -= amount
else:
# Player selling stock
self.own_stock_ownership[company_id] -= amount
self.cash += total_value # Add the proceeds to the seller's cash
return f"Sold {amount} stocks of {company_id}."
@ -491,7 +543,8 @@ class Company:
def make_decision(self, market, competitors):
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
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.
"""
def __init__(self, player_id, competitors_ids, market, risk_tolerance):
super().__init__(player_id, competitors_ids, market)
self.risk_tolerance = risk_tolerance
@ -724,7 +778,8 @@ class AICompany(Company):
"""
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):
"""
@ -758,7 +813,7 @@ class AICompany(Company):
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()
for ai in ai_competitors:
panel_text = Text()
@ -770,7 +825,16 @@ def print_ai_actions(ai_competitors):
# 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"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
console.print(Panel(panel_text, title=f"[bold]{ai.player_id}'s Status", border_style="grey50"))