/
RedResistance
/
Annomulator0
Обзор
Документация
Войти
/
RedResistance
/
Annomulator0
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
main.cpp
432 строки
12 KB
Domovoi-Kuzma
all refactored
06 июн 2026, 14:14
06 июн 2026, 14:14
7929d9f
Код
Авторство
О чём код?
#include <iostream> #include <vector> #include <string> #include <map> #include <fstream> #include <sstream> #include <algorithm> #include <cmath> using namespace std; enum HouseBuildPolicy { PEASANT_FILL_RATIO, GLOBAL_FILL_RATIO }; struct Resource { string name; }; struct Warehouse { double capacity = 0; map<Resource*, double> stored; }; struct Settlement { string name; Warehouse warehouse; map<Resource*, double> production; }; struct BuildCost { vector<pair<Resource*, double>> items; }; struct Need { Resource* resource = nullptr; int unlockPopulation = 0; double consumptionPer100 = 0; }; struct PopulationTier { string name; int level = 0; int maxPopulation = 0; double upgradeLimit = 1.0; vector<Need> needs; PopulationTier* next = nullptr; }; struct TierState { PopulationTier* tier = nullptr; int houses = 0; int population = 0; int unlockedNeeds = 0; vector<int> housesByPopulation; }; struct ProductionBuilding { string name; Resource* resource = nullptr; double productionPerMinute = 0; BuildCost buildCost; }; struct BuiltProduction { ProductionBuilding* building = nullptr; int count = 0; }; struct Event { int tick = 0; string command; vector<string> args; }; struct Simulation { int tick = 0; int secondsPerTick = 30; vector<Resource*> activeResources; map<PopulationTier*, TierState> tiers; vector<BuiltProduction> productions; vector<Event> events; Settlement playerIsland; Settlement northburg; Settlement sultan; map<Resource*, double> consumption; map<Resource*, double> production; map<Resource*, ProductionBuilding*> producerOf; BuildCost peasantHouseCost; HouseBuildPolicy houseBuildPolicy = GLOBAL_FILL_RATIO; double buildHouseThreshold = 0.90; map<string, Resource*> resourceByName; }; double peasantFillRatio(const Simulation& sim, PopulationTier* peasants) { const TierState& st = sim.tiers.at(peasants); if (st.houses == 0) return 0; return (double)st.population / ((double)st.houses * peasants->maxPopulation); } double globalFillRatio(const Simulation& sim) { long long population = 0; long long capacity = 0; for (auto& kv : sim.tiers) { PopulationTier* tier = kv.first; const TierState& st = kv.second; population += st.population; capacity += (long long)st.houses * tier->maxPopulation; } if (capacity == 0) return 0; return (double)population / capacity; } void growPopulation(Simulation& sim) { for (auto& kv : sim.tiers) { PopulationTier* tier = kv.first; TierState& state = kv.second; for (int pop = tier->maxPopulation - 1; pop >= 1; --pop) { int houses = state.housesByPopulation[pop]; if (!houses) continue; state.housesByPopulation[pop] -= houses; state.housesByPopulation[pop + 1] += houses; state.population += houses; } } } void updateUnlockedNeeds(Simulation& sim) { for (auto& kv : sim.tiers) { PopulationTier* tier = kv.first; TierState& state = kv.second; while (state.unlockedNeeds < (int)tier->needs.size()) { Need& need = tier->needs[state.unlockedNeeds]; if (state.population < need.unlockPopulation) break; state.unlockedNeeds++; if (find(sim.activeResources.begin(), sim.activeResources.end(), need.resource) == sim.activeResources.end()) sim.activeResources.push_back(need.resource); } } } void updateConsumptions(Simulation& sim) { sim.consumption.clear(); for (auto& kv : sim.tiers) { PopulationTier* tier = kv.first; TierState& state = kv.second; for (int i = 0; i < state.unlockedNeeds; i++) { Need& need = tier->needs[i]; sim.consumption[need.resource] += state.population * need.consumptionPer100 / 100.0; } } } void updateProductions(Simulation& sim) { sim.production.clear(); for (auto& p : sim.productions) sim.production[p.building->resource] += p.building->productionPerMinute * p.count; } string timeStr(int tick, int secPerTick) { int s = tick * secPerTick; int m = s / 60; s %= 60; char buf[32]; sprintf_s(buf, "%02d:%02d", m, s); return buf; } bool canBuild(Warehouse& w, const BuildCost& c) { for (auto& x : c.items) if (w.stored[x.first] < x.second) return false; return true; } void spend(Warehouse& w, const BuildCost& c) { for (auto& x : c.items) w.stored[x.first] -= x.second; } bool buildMissingProduction(Simulation& sim) { for (Resource* r : sim.activeResources) { double prod = sim.production[r]; double cons = sim.consumption[r]; if (prod >= cons) continue; ProductionBuilding* b = sim.producerOf[r]; if (!canBuild(sim.playerIsland.warehouse, b->buildCost)) continue; spend(sim.playerIsland.warehouse, b->buildCost); bool found = false; for (auto& p : sim.productions) { if (p.building != b) continue; p.count++; found = true; break; } if (!found) sim.productions.push_back({ b,1 }); cout << timeStr(sim.tick, sim.secondsPerTick) << " Build "<< b->name << "\n"; return true; } return false; } bool upgradeOneHouse(Simulation& sim) { for (auto& kv : sim.tiers) { PopulationTier* tier = kv.first; TierState& state = kv.second; if (!tier->next) continue; if (state.housesByPopulation[tier->maxPopulation] <= 0) continue; int housesAtOrHigher = 0; for (auto& kv2 : sim.tiers) if (kv2.first->level >= tier->level) housesAtOrHigher += kv2.second.houses; int minAllowed = (int)floor( housesAtOrHigher * tier->upgradeLimit); if (state.houses <= minAllowed) continue; state.housesByPopulation[tier->maxPopulation]--; state.houses--; state.population -= tier->maxPopulation; TierState& nextState = sim.tiers[tier->next]; nextState.housesByPopulation[tier->maxPopulation]++; nextState.houses++; nextState.population += tier->maxPopulation; cout<< timeStr(sim.tick, sim.secondsPerTick)<< " Upgrade " << tier->name << " -> " << tier->next->name << "\n"; return true; } return false; } void buildNewPeasantHouse(Simulation& sim, PopulationTier* peasants) { spend(sim.playerIsland.warehouse, sim.peasantHouseCost); TierState& state = sim.tiers[peasants]; state.housesByPopulation[1]++; state.houses++; state.population++; cout << timeStr(sim.tick, sim.secondsPerTick) << " Build Peasant House\n"; } bool canBuildNewPeasantHouse(Simulation& sim, PopulationTier* peasants) { TierState& state = sim.tiers[peasants]; double fillRatio; if (sim.houseBuildPolicy == PEASANT_FILL_RATIO) fillRatio = peasantFillRatio(sim, peasants); else fillRatio = globalFillRatio(sim); if (fillRatio < sim.buildHouseThreshold) { cout << "filled" << fillRatio<<"<"<<sim.buildHouseThreshold << endl; return false; } for (Resource* r : sim.activeResources) if (sim.production[r] < sim.consumption[r]) { cout << "produced" << sim.production[r] << "<" << sim.consumption[r] << endl; return false; } if (!canBuild(sim.playerIsland.warehouse, sim.peasantHouseCost)) { cout << "can't spend 2 wood" << endl; return false; } return true; } void updateWarehouse(Settlement& s) { for (auto& kv : s.production) { Resource* res = kv.first; double prod = kv.second; s.warehouse.stored[res] = min(prod + s.warehouse.stored[res], s.warehouse.capacity); } } void processEvents(Simulation& sim) { for (auto& e : sim.events) { if (e.tick != sim.tick) continue; if (e.command == "IMPORT") { string from = e.args[0]; string resource = e.args[1]; double amount = atof(e.args[2].c_str()); Settlement* src = nullptr; if (from == "Northburg") src = &sim.northburg; if (from == "Sultan") src = &sim.sultan; if (!src) continue; Resource* res = sim.resourceByName[resource]; if (!res) continue; double moved = min(src->warehouse.stored[res], amount); src->warehouse.stored[res] -= moved; sim.playerIsland.warehouse.stored[res] += moved; } else if (e.command == "ADD_CITY_PROD") { string resource = e.args[0]; double delta = atof(e.args[1].c_str()); Resource* res = sim.resourceByName[resource]; if (res) sim.playerIsland.production[res] += delta; } else if (e.command == "ADD_NORTHBURG_PROD") { string resource = e.args[0]; double delta = atof(e.args[1].c_str()); Resource* res = sim.resourceByName[resource]; if (res) sim.northburg.production[res] += delta; } else if (e.command == "ADD_SULTAN_PROD") { string resource = e.args[0]; double delta = atof(e.args[1].c_str()); Resource* res = sim.resourceByName[resource]; if (res) sim.sultan.production[res] += delta; } } } void updateWarehouses(Simulation& sim) { updateWarehouse(sim.playerIsland); updateWarehouse(sim.northburg); updateWarehouse(sim.sultan); } int main() { const int maxTick = 600000; Resource wood{ "Wood" }; Resource tools{ "Tools" }; Resource stone{ "Stone" }; Resource fish{ "Fish" }; Resource cider{ "Cider" }; Resource shirts{ "Shirts" }; PopulationTier peasants; PopulationTier citizens; peasants.name = "Peasants"; peasants.level = 0; peasants.maxPopulation = 8; peasants.upgradeLimit = 0.80; citizens.name = "Citizens"; citizens.level = 1; citizens.maxPopulation = 16; citizens.upgradeLimit = 0.60; peasants.next = &citizens; peasants.needs = { {&fish,0,1000}, {&cider,60,440} }; citizens.needs = { {&fish,0,1200}, {&cider,0,600}, {&shirts,24,500} }; ProductionBuilding fisher{ "Fishing Hut", &fish, 2000, {{{&wood,3},{&tools,2}}} }; ProductionBuilding ciderFarm{ "Cider Farm", &cider, 900, {{{&wood,4},{&tools,2}}} }; ProductionBuilding weaver{ "Weaver", &shirts, 600, {{{&wood,5},{&tools,3}}} }; Simulation sim; sim.resourceByName[fish.name] = &fish; sim.resourceByName[cider.name] = &cider; sim.resourceByName[shirts.name] = &shirts; sim.resourceByName[wood.name] = &wood; sim.resourceByName[tools.name] = &tools; sim.resourceByName[stone.name] = &stone; sim.secondsPerTick = 30; sim.peasantHouseCost = { { {&wood,2}} }; sim.playerIsland.name = "PlayerIsland"; sim.playerIsland.warehouse.capacity = 200; sim.northburg.name = "Northburg"; sim.northburg.warehouse.capacity = 5000; sim.sultan.name = "Sultan"; sim.sultan.warehouse.capacity = 5000; sim.playerIsland.warehouse.stored[&wood] = 40; sim.playerIsland.warehouse.stored[&tools] = 20; sim.northburg.warehouse.stored[&wood] = 1000; sim.northburg.warehouse.stored[&tools] = 1000; sim.tiers[&peasants] = { &peasants, 4, 4, 0, vector<int>(peasants.maxPopulation + 1,0) }; sim.tiers[&citizens] = { &citizens, 0, 0, 0, vector<int>(citizens.maxPopulation + 1,0) }; sim.tiers[&peasants].housesByPopulation[1] = 4; sim.activeResources.push_back(&fish); sim.productions.push_back({ &fisher,1 }); sim.producerOf[&fish] = &fisher; sim.producerOf[&cider] = &ciderFarm; sim.producerOf[&shirts] = &weaver; while (sim.tick < maxTick) { sim.tick++; processEvents(sim); updateWarehouses(sim); growPopulation(sim); updateUnlockedNeeds(sim); updateConsumptions(sim); updateProductions(sim); if (buildMissingProduction(sim)) continue; while (upgradeOneHouse(sim)) ; if (canBuildNewPeasantHouse(sim, &peasants)) buildNewPeasantHouse(sim, &peasants); } }