#include "../shared/ModuleBase.h" #include #include #include using json = nlohmann::json; namespace warfactory { /** * @brief Economy Module - Pure market simulation logic * * Handles supply/demand, pricing, trading * Claude Code works ONLY on this file (~200-300 lines max) */ class EconomyModule : public ModuleBase { private: struct MarketData { double price = 1.0; double supply = 0.0; double demand = 0.0; double base_price = 1.0; std::string trend = "stable"; }; std::map markets; double inflation_rate = 0.02; int simulation_tick = 0; public: EconomyModule() : ModuleBase("Economy") {} json process(const json& input) override { ensureInitialized(); std::string type = getField(input, "type"); if (type == "market_update") { return handleMarketUpdate(input); } else if (type == "trade") { return handleTrade(input); } else if (type == "get_prices") { return getPrices(); } else if (type == "simulate_tick") { return simulateTick(); } else if (type == "status") { return getStatus(); } return {{"error", "Unknown command type: " + type}}; } protected: void onInitialize(const json& config) override { // Initialize base markets if (config.contains("markets")) { auto market_config = config["markets"]; for (auto& [item, data] : market_config.items()) { MarketData market; market.base_price = getField(data, "base_price", 1.0); market.price = market.base_price; market.supply = getField(data, "initial_supply", 100.0); market.demand = getField(data, "initial_demand", 100.0); markets[item] = market; } } // Initialize default markets if none provided if (markets.empty()) { loadDefaultMarkets(); } inflation_rate = getField(module_config, "inflation_rate", 0.02); std::cout << "💰 Economy Module initialized with " << markets.size() << " markets" << std::endl; } private: json handleMarketUpdate(const json& input) { std::string item = getField(input, "item"); if (markets.find(item) == markets.end()) { // Create new market markets[item] = MarketData{}; } auto& market = markets[item]; if (input.contains("supply")) { market.supply = getField(input, "supply"); } if (input.contains("demand")) { market.demand = getField(input, "demand"); } // Recalculate price based on supply/demand updatePrice(item); return { {"status", "updated"}, {"item", item}, {"new_price", market.price}, {"supply", market.supply}, {"demand", market.demand}, {"trend", market.trend} }; } json handleTrade(const json& input) { std::string action = getField(input, "action"); std::string item = getField(input, "item"); double quantity = getField(input, "quantity"); if (markets.find(item) == markets.end()) { return {{"error", "Market not found for item: " + item}}; } auto& market = markets[item]; double current_price = market.price; if (action == "buy") { double max_price = getField(input, "max_price", 999999.0); if (current_price > max_price) { return { {"status", "trade_rejected"}, {"reason", "price_too_high"}, {"current_price", current_price}, {"max_price", max_price} }; } // Execute buy order market.demand += quantity; market.supply = std::max(0.0, market.supply - quantity); updatePrice(item); return { {"status", "trade_executed"}, {"action", "buy"}, {"item", item}, {"quantity", quantity}, {"price", current_price}, {"total_cost", quantity * current_price} }; } else if (action == "sell") { double min_price = getField(input, "min_price", 0.0); if (current_price < min_price) { return { {"status", "trade_rejected"}, {"reason", "price_too_low"}, {"current_price", current_price}, {"min_price", min_price} }; } // Execute sell order market.supply += quantity; market.demand = std::max(0.0, market.demand - quantity); updatePrice(item); return { {"status", "trade_executed"}, {"action", "sell"}, {"item", item}, {"quantity", quantity}, {"price", current_price}, {"total_revenue", quantity * current_price} }; } return {{"error", "Invalid trade action: " + action}}; } json getPrices() { json prices = json::object(); for (const auto& [item, market] : markets) { prices[item] = { {"price", market.price}, {"trend", market.trend}, {"supply", market.supply}, {"demand", market.demand} }; } return { {"market_data", prices}, {"inflation_rate", inflation_rate}, {"simulation_tick", simulation_tick} }; } json simulateTick() { simulation_tick++; // Simulate market fluctuations for (auto& [item, market] : markets) { // Add some random market movement double volatility = 0.05; // 5% volatility double random_factor = 1.0 + (rand() / (double)RAND_MAX - 0.5) * volatility; // Natural decay towards equilibrium double equilibrium_ratio = market.demand / std::max(market.supply, 1.0); market.price = market.base_price * equilibrium_ratio * random_factor; // Apply inflation market.base_price *= (1.0 + inflation_rate / 100.0); updateTrend(item); } return { {"status", "tick_processed"}, {"simulation_tick", simulation_tick}, {"markets_updated", markets.size()} }; } json getStatus() { return { {"module", "Economy"}, {"markets_count", markets.size()}, {"simulation_tick", simulation_tick}, {"inflation_rate", inflation_rate} }; } void updatePrice(const std::string& item) { auto& market = markets[item]; if (market.supply <= 0) { market.price = market.base_price * 2.0; // Scarcity premium } else { double ratio = market.demand / market.supply; market.price = market.base_price * std::max(0.1, ratio); } updateTrend(item); } void updateTrend(const std::string& item) { auto& market = markets[item]; double ratio = market.demand / std::max(market.supply, 1.0); if (ratio > 1.2) { market.trend = "rising"; } else if (ratio < 0.8) { market.trend = "falling"; } else { market.trend = "stable"; } } void loadDefaultMarkets() { markets["iron_ore"] = {1.0, 100.0, 100.0, 1.0, "stable"}; markets["copper_ore"] = {1.2, 80.0, 90.0, 1.2, "stable"}; markets["coal"] = {0.8, 120.0, 100.0, 0.8, "stable"}; markets["steel_plate"] = {5.0, 50.0, 60.0, 5.0, "stable"}; markets["copper_wire"] = {2.0, 70.0, 75.0, 2.0, "stable"}; markets["circuit"] = {15.0, 20.0, 25.0, 15.0, "stable"}; } }; } // namespace warfactory // C-style export functions for dynamic loading extern "C" { warfactory::IModule* createModule() { return new warfactory::EconomyModule(); } void destroyModule(warfactory::IModule* module) { delete module; } const char* getModuleName() { return "Economy"; } }