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();
- }
|