Universe.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //
  2. // Created by jovian on 17/08/17.
  3. //
  4. #include <iostream>
  5. #include "Universe.h"
  6. Universe::Universe() {}
  7. Universe::~Universe() {
  8. // Planets
  9. while (!m_planets.empty()) {
  10. if (m_planets.back() != nullptr)
  11. delete m_planets.back();
  12. m_planets.pop_back();
  13. }
  14. // Ships
  15. m_travellingShips.clear();
  16. while (!m_ships.empty()) {
  17. if (m_ships.back() != nullptr)
  18. delete m_ships.back();
  19. m_ships.pop_back();
  20. }
  21. // Rules
  22. while (!m_rules.empty()) {
  23. if (m_rules.back() != nullptr)
  24. delete m_rules.back();
  25. m_rules.pop_back();
  26. }
  27. }
  28. void Universe::collectVisuals(std::vector<Visual *> &scope) {
  29. // Sun
  30. scope.push_back(new Visual(13, b2Vec2(0.0f, 0.0f), 0.0f));
  31. // Planets
  32. for (auto it(m_planets.begin()); it != m_planets.end(); it++)
  33. scope.push_back((*it)->makeVisual());
  34. // Ships
  35. for (auto it(m_travellingShips.begin()); it != m_travellingShips.end(); it++)
  36. scope.push_back((*it)->makeVisual());
  37. }
  38. void Universe::update() {
  39. // Apply rules on planets
  40. for (auto it_r(m_rules.begin()); it_r != m_rules.end(); it_r++) {
  41. for (auto it_p(m_planets.begin()); it_p != m_planets.end(); it_p++) {
  42. (*it_p)->applyRule(*it_r);
  43. }
  44. }
  45. // Move ships
  46. for (auto it(m_travellingShips.begin()); it != m_travellingShips.end(); it++)
  47. (*it)->update();
  48. }
  49. void Universe::routeShips() {
  50. // Check ready ships
  51. bool ready(false);
  52. auto it1(m_planets.begin());
  53. while (it1 != m_planets.end() && !ready) {
  54. ready = (*it1)->readyShip();
  55. it1++;
  56. }
  57. // Compute needs
  58. if (ready) {
  59. // Compute average
  60. Stock avrg;
  61. for (auto it(m_planets.begin()); it != m_planets.end(); it++)
  62. avrg += (*it)->getDef().stock;
  63. avrg /= m_planets.size();
  64. // Send ships
  65. StarShip *ship(nullptr);
  66. Resource majRes;
  67. for (auto it(m_planets.begin()); it != m_planets.end(); it++) {
  68. if ((*it)->readyShip()) {
  69. // Get ship and most resource
  70. ship = (*it)->launchShip(avrg);
  71. b2Vec2 from(ship->getDef().pos);
  72. majRes = ship->getDef().stock.mostResource();
  73. // Seek a ideal planet
  74. auto spottedPlanet(m_planets.begin());
  75. bool notFound(true);
  76. if (ship->getDef().stock.get(majRes) == 0) {
  77. // Seek a master planet
  78. for (auto itp(m_planets.begin()++); itp != m_planets.end(); itp++) {
  79. if (!(*itp)->need(PEOPLE, avrg) && (*itp)->getId() != (*it)->getId() &&
  80. (notFound || b2Distance((*spottedPlanet)->getDef().pos, from) >
  81. b2Distance((*itp)->getDef().pos, from))) {
  82. spottedPlanet = itp;
  83. notFound = false;
  84. }
  85. }
  86. } else {
  87. // Seek a needed planet
  88. for (auto itp(m_planets.begin()++); itp != m_planets.end(); itp++) {
  89. if ((*itp)->need(majRes, avrg) && (*itp)->getId() != (*it)->getId() &&
  90. (notFound || b2Distance((*spottedPlanet)->getDef().pos, from) >
  91. b2Distance((*itp)->getDef().pos, from))) {
  92. spottedPlanet = itp;
  93. notFound = false;
  94. }
  95. }
  96. }
  97. // Go toward this planet
  98. ship->travelTo((*spottedPlanet)->getId(), (*spottedPlanet)->getDef().pos);
  99. m_travellingShips.insert(ship);
  100. }
  101. }
  102. }
  103. // Check arrived ships
  104. auto it2(m_travellingShips.begin());
  105. while (it2 != m_travellingShips.end()) {
  106. if ((*it2)->isArrived()) {
  107. m_planets[(*it2)->getTargetPlanet()]->landShip(*it2);
  108. it2 = m_travellingShips.erase(it2);
  109. } else {
  110. it2++;
  111. }
  112. }
  113. }
  114. void Universe::createRandomUniverse() {
  115. // todo better Universe::createRandomUniverse()
  116. // Hand crafted universe
  117. PlanetDef def;
  118. for (int k(0); k < 12; k++) {
  119. def.pos.Set((float)rand() / RAND_MAX * 8.0f - 4.0f, (float)rand() / RAND_MAX * 8.0f - 4.0f);
  120. def.size = 0.2f + (float)rand() / RAND_MAX * 2.0f;
  121. m_planets.push_back(new Planet(def));
  122. }
  123. def.pos.Set(1.0f, 1.0f);
  124. def.stock.set(PEOPLE, 2);
  125. def.name = "Earth";
  126. def.size = 1.2f;
  127. m_planets.push_back(new Planet(def));
  128. // Debug ship
  129. StarShipDef s_def;
  130. s_def.stock.set(PEOPLE, 10);
  131. s_def.pos = b2Vec2(5.0f, 1.3f); // m_planets[2]->getDef().pos
  132. StarShip *myShip(new StarShip(s_def));
  133. myShip->travelTo(m_planets[2]->getId(), m_planets[2]->getDef().pos);
  134. m_ships.push_back(myShip);
  135. m_travellingShips.insert(myShip);
  136. }
  137. void Universe::addRule(PlanetStep *rule) {
  138. m_rules.push_back(rule);
  139. }
  140. const PlanetDef Universe::getNearestPlanetInfo(b2Vec2 from) {
  141. // Void system
  142. if (m_planets.empty())
  143. return PlanetDef();
  144. // Search minimum
  145. auto spottedPlanet(m_planets.begin());
  146. for (auto it(m_planets.begin()++); it != m_planets.end(); it++) {
  147. if (b2Distance((*spottedPlanet)->getDef().pos, from) > b2Distance((*it)->getDef().pos, from))
  148. spottedPlanet = it;
  149. }
  150. // Return def
  151. return (*spottedPlanet)->getDef();
  152. }