- 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>
287 lines
8.7 KiB
C++
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";
|
|
}
|
|
} |