[upd] Refine energy cost calculations and enhance price adjustments in market and BDI agent logic. Implement rounding for improved accuracy in financial computations and adjust supply/demand thresholds for better market dynamics.
This commit is contained in:
parent
73e4712119
commit
a161988dbf
@ -103,7 +103,7 @@ def get_energy_cost(resource_type: ResourceType) -> int:
|
||||
return 10
|
||||
energy_cost = abs(config.energy_cost)
|
||||
avg_output = max(1, (config.min_output + config.max_output) / 2) if config.output_resource else 1
|
||||
return int(energy_cost / avg_output)
|
||||
return int(round(energy_cost / avg_output))
|
||||
|
||||
|
||||
# Cached config values to avoid repeated lookups
|
||||
|
||||
@ -438,6 +438,7 @@ class BDIAgentAI:
|
||||
return self._create_gather_fallback(target_resource, reason, goal, plan, bdi_info)
|
||||
|
||||
# Calculate quantity to buy
|
||||
# Use max(1, ...) to avoid division by zero
|
||||
can_afford = self.agent.money // max(1, order.price_per_unit)
|
||||
space = self.agent.inventory_space()
|
||||
quantity = min(2, can_afford, space, order.quantity)
|
||||
@ -540,7 +541,7 @@ class BDIAgentAI:
|
||||
min_price = getattr(economy, 'min_price', 100) if economy else 100
|
||||
|
||||
energy_cost = get_energy_cost(resource_type)
|
||||
fair_value = max(min_price, int(energy_cost * energy_to_money_ratio))
|
||||
fair_value = max(min_price, int(round(energy_cost * energy_to_money_ratio)))
|
||||
|
||||
# Apply trading skill
|
||||
sell_modifier = get_trade_price_modifier(self.skills.trading, is_buying=False)
|
||||
@ -549,15 +550,17 @@ class BDIAgentAI:
|
||||
signal = self.market.get_market_signal(resource_type)
|
||||
|
||||
if signal == "sell": # Scarcity
|
||||
price = int(fair_value * 1.3 * sell_modifier)
|
||||
price = int(round(fair_value * 1.3 * sell_modifier))
|
||||
elif signal == "hold":
|
||||
price = int(fair_value * sell_modifier)
|
||||
price = int(round(fair_value * sell_modifier))
|
||||
else: # Surplus
|
||||
cheapest = self.market.get_cheapest_order(resource_type)
|
||||
if cheapest and cheapest.seller_id != self.agent.id:
|
||||
price = max(min_price, cheapest.price_per_unit - 1)
|
||||
# Undercut, but respect floor (80% of fair value or min_price)
|
||||
floor_price = max(min_price, int(round(fair_value * 0.8)))
|
||||
price = max(floor_price, cheapest.price_per_unit - 1)
|
||||
else:
|
||||
price = int(fair_value * 0.8 * sell_modifier)
|
||||
price = int(round(fair_value * 0.8 * sell_modifier))
|
||||
|
||||
return max(min_price, price)
|
||||
|
||||
|
||||
@ -296,7 +296,7 @@ def create_buy_action(resource_type: ResourceType) -> GOAPAction:
|
||||
|
||||
def cost(state: WorldState) -> float:
|
||||
# Trading cost is low (1 energy)
|
||||
base_cost = 0.5
|
||||
base_cost = 0.2
|
||||
|
||||
# MILD profession effect for trading (everyone should be able to trade)
|
||||
# Traders get a bonus, but non-traders shouldn't be heavily penalized
|
||||
|
||||
@ -133,8 +133,8 @@ def _create_hunt() -> GOAPAction:
|
||||
|
||||
def effects(state: WorldState) -> dict:
|
||||
# Account for success chance
|
||||
effective_meat = int(expected * config.success_chance)
|
||||
effective_hide = int(1 * config.success_chance) # Average hide
|
||||
effective_meat = int(round(expected * config.success_chance))
|
||||
effective_hide = int(round(1 * config.success_chance)) # Average hide
|
||||
|
||||
energy_spent = abs(config.energy_cost) / 50.0
|
||||
|
||||
@ -295,7 +295,7 @@ def _create_sell_action(resource_type: ResourceType, min_keep: int = 1) -> GOAPA
|
||||
def effects(state: WorldState) -> dict:
|
||||
# Estimate we'll get a reasonable price (around min_price from config)
|
||||
# This is approximate - actual execution will get real prices
|
||||
estimated_price = 100 # Base estimate (min_price from config)
|
||||
estimated_price = 150 # Better estimate than min_price (fair value)
|
||||
|
||||
current = getattr(state, count_name)
|
||||
sell_qty = min(3, current - min_keep) # Sell up to 3, keep minimum
|
||||
|
||||
@ -63,7 +63,7 @@ class Order:
|
||||
def apply_discount(self, percentage: float = 0.1) -> None:
|
||||
"""Apply a discount to the price."""
|
||||
min_price = _get_min_price()
|
||||
reduction = max(1, int(self.price_per_unit * percentage))
|
||||
reduction = max(1, int(round(self.price_per_unit * percentage)))
|
||||
self.price_per_unit = max(min_price, self.price_per_unit - reduction)
|
||||
|
||||
def adjust_price(self, new_price: int, current_turn: int) -> bool:
|
||||
@ -154,9 +154,9 @@ class OrderBook:
|
||||
DISCOUNT_RATE: float = 0.12
|
||||
|
||||
# Supply/demand thresholds
|
||||
LOW_SUPPLY_THRESHOLD: int = 3 # Less than this = scarcity
|
||||
HIGH_SUPPLY_THRESHOLD: int = 10 # More than this = surplus
|
||||
DEMAND_DECAY: float = 0.95 # How fast demand score decays per turn
|
||||
LOW_SUPPLY_THRESHOLD: int = 10 # Less than this = scarcity
|
||||
HIGH_SUPPLY_THRESHOLD: int = 50 # More than this = surplus
|
||||
DEMAND_DECAY: float = 0.99 # How fast demand score decays per turn
|
||||
|
||||
def __post_init__(self):
|
||||
"""Initialize price history and load config values."""
|
||||
@ -266,7 +266,8 @@ class OrderBook:
|
||||
total_cost = actual_quantity * order.price_per_unit
|
||||
if buyer_money < total_cost:
|
||||
# Try to buy what they can afford
|
||||
actual_quantity = buyer_money // order.price_per_unit
|
||||
# Use max(1, ...) to avoid division by zero, though price is min 100
|
||||
actual_quantity = buyer_money // max(1, order.price_per_unit)
|
||||
if actual_quantity <= 0:
|
||||
return TradeResult(
|
||||
success=False,
|
||||
@ -376,7 +377,7 @@ class OrderBook:
|
||||
# Use average sale price as reference if available
|
||||
reference_price = base_price
|
||||
if history.avg_sale_price > 0:
|
||||
reference_price = int((base_price + history.avg_sale_price) / 2)
|
||||
reference_price = int(round((base_price + history.avg_sale_price) / 2))
|
||||
|
||||
# Adjust based on supply/demand
|
||||
if ratio < 0.7: # Scarcity - raise price
|
||||
@ -387,7 +388,7 @@ class OrderBook:
|
||||
else:
|
||||
price_multiplier = 1.0
|
||||
|
||||
suggested = int(reference_price * price_multiplier)
|
||||
suggested = int(round(reference_price * price_multiplier))
|
||||
return max(_get_min_price(), suggested)
|
||||
|
||||
def adjust_order_price(self, order_id: str, seller_id: str, new_price: int, current_turn: int) -> bool:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user