| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 | //// Created by jovian on 17/08/17.//#include <iostream>#include "Universe.h"Universe::Universe() {}Universe::~Universe() {    // Planets    while (!m_planets.empty()) {        if (m_planets.back() != nullptr)            delete m_planets.back();        m_planets.pop_back();    }    // Ships    m_travellingShips.clear();    while (!m_ships.empty()) {        if (m_ships.back() != nullptr)            delete m_ships.back();        m_ships.pop_back();    }    // Rules    while (!m_rules.empty()) {        if (m_rules.back() != nullptr)            delete m_rules.back();        m_rules.pop_back();    }}void Universe::collectVisuals(std::vector<Visual *> &scope) {    // Sun    scope.push_back(new Visual(13, b2Vec2(0.0f, 0.0f), 0.0f));    // Planets    for (auto it(m_planets.begin()); it != m_planets.end(); it++)        scope.push_back((*it)->makeVisual());    // Ships    for (auto it(m_travellingShips.begin()); it != m_travellingShips.end(); it++)        scope.push_back((*it)->makeVisual());}void Universe::update() {    // Apply rules on planets    for (auto it_r(m_rules.begin()); it_r != m_rules.end(); it_r++) {        for (auto it_p(m_planets.begin()); it_p != m_planets.end(); it_p++) {            (*it_p)->applyRule(*it_r);        }    }    // Move ships    for (auto it(m_travellingShips.begin()); it != m_travellingShips.end(); it++)        (*it)->update();}void Universe::routeShips() {    // Check ready ships    bool ready(false);    auto it1(m_planets.begin());    while (it1 != m_planets.end() && !ready) {        ready = (*it1)->readyShip();        it1++;    }    // Compute needs    if (ready) {        // Compute average        Stock avrg;        for (auto it(m_planets.begin()); it != m_planets.end(); it++)            avrg += (*it)->getDef().stock;        avrg /= m_planets.size();        // Send ships        StarShip *ship(nullptr);        Resource majRes;        for (auto it(m_planets.begin()); it != m_planets.end(); it++) {            if ((*it)->readyShip()) {                // Get ship and most resource                ship = (*it)->launchShip(avrg);                b2Vec2 from(ship->getDef().pos);                majRes = ship->getDef().stock.mostResource();                // Seek a ideal planet                auto spottedPlanet(m_planets.begin());                bool notFound(true);                if (ship->getDef().stock.get(majRes) == 0) {                    // Seek a master planet                    for (auto itp(m_planets.begin()++); itp != m_planets.end(); itp++) {                        if (!(*itp)->need(PEOPLE, avrg) && (*itp)->getId() != (*it)->getId() &&                            (notFound || b2Distance((*spottedPlanet)->getDef().pos, from) >                                         b2Distance((*itp)->getDef().pos, from))) {                            spottedPlanet = itp;                            notFound = false;                        }                    }                } else {                    // Seek a needed planet                    for (auto itp(m_planets.begin()++); itp != m_planets.end(); itp++) {                        if ((*itp)->need(majRes, avrg) && (*itp)->getId() != (*it)->getId() &&                            (notFound || b2Distance((*spottedPlanet)->getDef().pos, from) >                                         b2Distance((*itp)->getDef().pos, from))) {                            spottedPlanet = itp;                            notFound = false;                        }                    }                }                // Go toward this planet                ship->travelTo((*spottedPlanet)->getId(), (*spottedPlanet)->getDef().pos);                m_travellingShips.insert(ship);            }        }    }    // Check arrived ships    auto it2(m_travellingShips.begin());    while (it2 != m_travellingShips.end()) {        if ((*it2)->isArrived()) {            m_planets[(*it2)->getTargetPlanet()]->landShip(*it2);            it2 = m_travellingShips.erase(it2);        } else {            it2++;        }    }}void Universe::createRandomUniverse() {    // todo better Universe::createRandomUniverse()    // Hand crafted universe    PlanetDef def;    for (int k(0); k < 12; k++) {        def.pos.Set((float)rand() / RAND_MAX * 8.0f - 4.0f, (float)rand() / RAND_MAX * 8.0f - 4.0f);        def.size = 0.2f + (float)rand() / RAND_MAX * 2.0f;        m_planets.push_back(new Planet(def));    }    def.pos.Set(1.0f, 1.0f);    def.stock.set(PEOPLE, 2);    def.name = "Earth";    def.size = 1.2f;    m_planets.push_back(new Planet(def));    // Debug ship    StarShipDef s_def;    s_def.stock.set(PEOPLE, 10);    s_def.pos = b2Vec2(5.0f, 1.3f); // m_planets[2]->getDef().pos    StarShip *myShip(new StarShip(s_def));    myShip->travelTo(m_planets[2]->getId(), m_planets[2]->getDef().pos);    m_ships.push_back(myShip);    m_travellingShips.insert(myShip);}void Universe::addRule(PlanetStep *rule) {    m_rules.push_back(rule);}const PlanetDef Universe::getNearestPlanetInfo(b2Vec2 from) {    // Void system    if (m_planets.empty())        return PlanetDef();    // Search minimum    auto spottedPlanet(m_planets.begin());    for (auto it(m_planets.begin()++); it != m_planets.end(); it++) {        if (b2Distance((*spottedPlanet)->getDef().pos, from) > b2Distance((*it)->getDef().pos, from))            spottedPlanet = it;    }    // Return def    return (*spottedPlanet)->getDef();}
 |