warfactoryracine/modules/economy/src/EconomyModule.cpp
StillHammer 61ef2293ad Replace engine architecture with modular triple interface system
- Remove old 10-engine system (engines/ directory deleted)
- Implement C++ triple interface architecture:
  * IEngine: Execution coordination (Debug → Production)
  * IModuleSystem: Strategy pattern (Sequential → Threaded → Cluster)
  * IModule: Pure game logic interface (200-300 lines per module)
  * IIO: Communication transport (Intra → Local → Network)

- Add autonomous module structure:
  * modules/factory/: Production logic with autonomous build
  * modules/economy/: Market simulation with autonomous build
  * modules/logistic/: Supply chain with autonomous build
  * Each module: CLAUDE.md + CMakeLists.txt + shared/ + build/

- Benefits for Claude Code development:
  * Ultra-focused contexts (200 lines vs 50K+ lines)
  * Autonomous builds (cmake . from module directory)
  * Hot-swappable infrastructure without logic changes
  * Parallel development across multiple Claude instances

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-20 09:15:03 +08:00

287 lines
8.7 KiB
C++

#include "../shared/ModuleBase.h"
#include <iostream>
#include <map>
#include <cmath>
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<std::string, MarketData> 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<std::string>(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<double>(data, "base_price", 1.0);
market.price = market.base_price;
market.supply = getField<double>(data, "initial_supply", 100.0);
market.demand = getField<double>(data, "initial_demand", 100.0);
markets[item] = market;
}
}
// Initialize default markets if none provided
if (markets.empty()) {
loadDefaultMarkets();
}
inflation_rate = getField<double>(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<std::string>(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<double>(input, "supply");
}
if (input.contains("demand")) {
market.demand = getField<double>(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<std::string>(input, "action");
std::string item = getField<std::string>(input, "item");
double quantity = getField<double>(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<double>(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<double>(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";
}
}