city.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. #include "city.h"
  2. #include "cell.h"
  3. #include "building.h"
  4. #include "json.hpp"
  5. #include "loan.h"
  6. #include <iostream>
  7. #include <set>
  8. #include <fstream>
  9. #include <sstream>
  10. #include <random>
  11. using namespace std;
  12. using json = nlohmann::json;
  13. const std::string PURPLE = "\033[35m";
  14. void cursor::up(){ if(y > 0) --y;}
  15. void cursor::down(){ if(y < (limit_y - 1)) ++y; }
  16. void cursor::left(){ if(x > 0) --x; }
  17. void cursor::right(){ if(x < (limit_x - 1)) ++x; }
  18. int cursor::posx() const{ return x; }
  19. int cursor::posy() const{ return y; }
  20. int cursor::limitx() const{ return limit_x; }
  21. int cursor::limity() const{ return limit_y; }
  22. void city::unemploy_cell(int x, int y){
  23. vector<pair<int, int>> employment_vector = _map[x][y].get_employment_vector();
  24. vector<pair<int, int>>::iterator begin = employment_vector.begin();
  25. while(begin != employment_vector.end()){
  26. _map[(*begin).first][(*begin).second].delete_employment(x,y);
  27. if(_map[(*begin).first][(*begin).second].get_building().get_type() == RESIDENTIAL)
  28. _unemployment_vector.push_back(pair<int,int>((*begin).first,(*begin).second));
  29. begin++;
  30. }
  31. _map[x][y].clear_employment();
  32. if(_map[x][y].get_building().get_type() == RESIDENTIAL)
  33. _unemployment_vector.push_back(pair<int,int>(x,y));
  34. }
  35. void city::employ_cell(int x, int y){
  36. if(_unemployment_vector.size() > 0 && (_map[x][y].get_building().get_type() == INDUSTRY || _map[x][y].get_building().get_type() == SHOPS)){
  37. pair<int, int> c2 = _unemployment_vector[0];
  38. _map[x][y].set_employment(c2.first, c2.second);
  39. _map[c2.first][c2.second].set_employment(x, y);
  40. _unemployment_vector.erase(_unemployment_vector.begin());
  41. }
  42. }
  43. void city::road_traffic(int i, int e){
  44. vector<pair<int,int>> employment = _map[i][e].get_employment_vector();
  45. for(size_t x = 0; x < employment.size(); ++x){
  46. vector<pair<int,int>> route = smaller_route(i, e, employment[x].first, employment[x].second);
  47. for(size_t r = 0; r < route.size(); ++r){
  48. _map[route[r].first][route[r].second].set_traffic(_map[route[r].first][route[r].second].get_traffic() + 1);
  49. }
  50. }
  51. }
  52. /*
  53. * direction:
  54. * 0: up
  55. * 1: right
  56. * 2: down
  57. * 3: left
  58. */
  59. pair<int,int> city::get_near_road(int i, int e){
  60. int direction = 0;
  61. int local = _map[i][e].get_access();
  62. if(e > 0 && _map[i][e - 1].get_access() > local)
  63. direction = 3;
  64. else if(i > 0 && _map[i - 1][e].get_access() > local)
  65. direction = 0;
  66. else if(e < int(_map[i].size()) && _map[i][e + 1].get_access() > local)
  67. direction = 1;
  68. else if(i < int(_map.size()) && _map[i + 1][e].get_access() > local)
  69. direction = 2;
  70. switch(direction){
  71. case 0:{
  72. int x = i, y = e;
  73. while(x > 0 && _map[x][y].get_building().get_type() != ROAD){
  74. --x;
  75. }
  76. return make_pair(x,y);
  77. };break;
  78. case 1:{
  79. int x = i, y = e;
  80. while(y < int(_map[x].size()) && _map[x][y].get_building().get_type() != ROAD){
  81. ++y;
  82. }
  83. return make_pair(x,y);
  84. };break;
  85. case 2:{
  86. int x = i, y = e;
  87. while(x < int(_map.size()) && _map[x][y].get_building().get_type() != ROAD){
  88. ++x;
  89. }
  90. return make_pair(x,y);
  91. };break;
  92. case 3:{
  93. int x = i, y = e;
  94. while(y > 0 && _map[x][y].get_building().get_type() != ROAD){
  95. --y;
  96. }
  97. return make_pair(x,y);
  98. };break;
  99. }
  100. return make_pair(-1,-1);
  101. }
  102. int city::positions_to_node(int i, int e){
  103. return i * _map.size() + e;
  104. }
  105. void city::pay_bigger_city(){
  106. int previous_size = _size;
  107. if(_money >= (_size + 1) * 10){
  108. _size += 1;
  109. vector<cell> c(_size, cell());
  110. _money -= _size * 10;
  111. for(int i = 0; i < previous_size; ++i){
  112. _map[i].push_back(cell());
  113. }
  114. _map.push_back(c);
  115. }
  116. }
  117. pair<int,int> city::node_to_positions(int node) {
  118. return make_pair(node / _map.size(), node % _map.size());
  119. }
  120. vector<pair<int,int>> city::dijkstra(int x, int y, int dest_x, int dest_y) {
  121. int max = _map[x].size() * _map.size();
  122. int n = max;
  123. int start_node = positions_to_node(x,y);
  124. int end_node = positions_to_node(dest_x,dest_y);
  125. int cost[max][max], distance[max], pred[max];
  126. int visited[max], count, min_distance, next_node = -1, i, j;
  127. for(i = 0;i < n; i++){
  128. for(j = 0; j < n ; j++){
  129. pair<int, int> origin = node_to_positions(i);
  130. pair<int, int> destination = node_to_positions(j);
  131. cost[i][j] = int(INFINITY);
  132. if(i == j)
  133. cost[i][j] = 0;
  134. else{
  135. int z = 0;
  136. bool near = false;
  137. if(origin.first + 1 == destination.first)
  138. --z;
  139. if(origin.second + 1 == destination.second)
  140. --z;
  141. if(origin.first == destination.first){
  142. near = true;
  143. ++z;
  144. }
  145. if(origin.second == destination.second){
  146. ++z;
  147. near = true;
  148. }
  149. if(origin.first -1 == destination.first)
  150. --z;
  151. if(origin.second - 1 == destination.second)
  152. --z;
  153. if(z == 0 && near && _map[origin.first][origin.second].get_building().get_type() == ROAD && _map[destination.first][destination.second].get_building().get_type() == ROAD){
  154. cost[i][j] = 1;
  155. }else{
  156. cost[i][j] = int(INFINITY);
  157. }
  158. }
  159. }
  160. }
  161. for(i = 0; i < n; i++) {
  162. distance[i] = cost[start_node][i];
  163. pred[i] = start_node;
  164. visited[i] = 0;
  165. }
  166. pair<int, int> previous_node;
  167. distance[start_node] = 0;
  168. visited[start_node] = 1;
  169. count = 1;
  170. while(count < n - 1) {
  171. min_distance = int(INFINITY);
  172. for(i = 0; i < n; i++) {
  173. //TODO: Match differences between direction and one way road
  174. if(i > 0 && _map[node_to_positions(i).first][node_to_positions(i).second].get_building().get_type() == ONE_WAY_ROAD) {
  175. previous_node = node_to_positions(pred[i - 1]);
  176. pair<int,int> prev_positions = previous_node;
  177. pair<int,int> next_positions = node_to_positions(i);
  178. int x = prev_positions.first - next_positions.first;
  179. int y = prev_positions.second - next_positions.second;
  180. int direction = _map[node_to_positions(i).first][node_to_positions(i).second].get_direction();
  181. if( !(x > 0 && direction == 1) || !(x < 0 && direction == 2) || !(y < 0 && direction == 3) || !(y > 0 && direction == 4)){
  182. distance[i] = int(INFINITY);
  183. }
  184. }
  185. if(distance[i] < min_distance && !visited[i]) {
  186. min_distance = distance[i];
  187. next_node = i;
  188. }
  189. }
  190. if(next_node != -1){
  191. visited[next_node] = 1;
  192. for(i = 0; i < n; i++)
  193. if(!visited[i])
  194. if(min_distance + cost[next_node][i] < distance[i]) {
  195. distance[i] = min_distance + cost[next_node][i];
  196. pred[i] = next_node;
  197. }
  198. }
  199. count++;
  200. }
  201. vector<pair<int,int>> v;
  202. if(distance[end_node] != int(INFINITY)){
  203. int temp_node = end_node;
  204. pair<int,int> p = node_to_positions(temp_node);
  205. do {
  206. temp_node = pred[temp_node];
  207. p = node_to_positions(temp_node);
  208. v.push_back(p);
  209. }while(temp_node != start_node);
  210. }
  211. return v;
  212. }
  213. vector<pair<int,int>> city::smaller_route(int origin_x, int origin_y, int destination_x, int destination_y){
  214. pair<int, int> origin = get_near_road(origin_x, origin_y);
  215. pair<int, int> destination = get_near_road(destination_x, destination_y);
  216. return dijkstra(origin.first, origin.second, destination.first, destination.second);
  217. }
  218. city::city(const string& name, int money, int size): _name(name),
  219. _money(money), _size(size), _time(32), _population(0), _residentials(0), _shops(0), _industry(0),
  220. _select(cursor(0, 0, size, size)), _waste(0){
  221. ifstream in(_name + ".json");
  222. if(in){
  223. try{
  224. load();
  225. }catch(...){ create(); }
  226. }else{
  227. create();
  228. }
  229. }
  230. void city::print(){
  231. cout << "\nType------------" << endl;
  232. for(unsigned i = 0; i < _map.size(); ++i){
  233. for(unsigned e = 0; e < _map[i].size(); ++e){
  234. if(_select.posx() == int(e) && _select.posy() == int(i))
  235. cout << PURPLE << _map[e][i].get_building().get_type() << " " << _map[e][i].clear_color();
  236. else
  237. cout << _map[e][i].color_by_type() << _map[e][i].get_building().get_type() << " " << _map[e][i].clear_color();
  238. }
  239. cout << endl;
  240. }
  241. cout << "Electricity-------" << endl;
  242. for(unsigned i = 0; i < _map.size(); ++i){
  243. for(unsigned e = 0; e < _map[i].size(); ++e){
  244. if(_select.posx() == int(e) && _select.posy() == int(i))
  245. cout << PURPLE << _map[e][i].get_electricity() << " " << _map[e][i].clear_color();
  246. else
  247. cout << _map[e][i].color_by_electricity() << _map[e][i].get_electricity() << " " << _map[e][i].clear_color();
  248. }
  249. cout << endl;
  250. }
  251. cout << "Water-------" << endl;
  252. for(unsigned i = 0; i < _map.size(); ++i){
  253. for(unsigned e = 0; e < _map[i].size(); ++e){
  254. if(_select.posx() == int(e) && _select.posy() == int(i))
  255. cout << PURPLE << _map[e][i].get_water() << " " << _map[e][i].clear_color();
  256. else
  257. cout << _map[e][i].color_by_water() << _map[e][i].get_water() << " " << _map[e][i].clear_color();
  258. }
  259. cout << endl;
  260. }
  261. cout << "Pollution---------" << endl;
  262. for(unsigned i = 0; i < _map.size(); ++i){
  263. for(unsigned e = 0; e < _map[i].size(); ++e){
  264. if(_select.posx() == int(e) && _select.posy() == int(i))
  265. cout << PURPLE << _map[e][i].get_air_pollution() << " " << _map[e][i].clear_color();
  266. else
  267. cout << _map[e][i].color_by_pollution() << _map[e][i].get_air_pollution() << " " << _map[e][i].clear_color();
  268. }
  269. cout << endl;
  270. }
  271. cout << "Access------------" << endl;
  272. for(unsigned i = 0; i < _map.size(); ++i){
  273. for(unsigned e = 0; e < _map[i].size(); ++e){
  274. if(_select.posx() == int(e) && _select.posy() == int(i))
  275. cout << PURPLE << _map[e][i].get_access() << " " << _map[e][i].clear_color();
  276. else
  277. cout << _map[e][i].color_by_access() << _map[e][i].get_access() << " " << _map[e][i].clear_color();
  278. }
  279. cout << endl;
  280. }
  281. cout << "Traffic------------" << endl;
  282. for(unsigned i = 0; i < _map.size(); ++i){
  283. for(unsigned e = 0; e < _map[i].size(); ++e){
  284. if(_select.posx() == int(e) && _select.posy() == int(i))
  285. cout << PURPLE << _map[e][i].get_traffic() << " " << _map[e][i].clear_color();
  286. else
  287. cout << _map[e][i].color_by_traffic() << _map[e][i].get_traffic() << " " << _map[e][i].clear_color();
  288. }
  289. cout << endl;
  290. }
  291. cout << "working people------------" << endl;
  292. int workers = 0;
  293. int jobs = 0;
  294. for(unsigned i = 0; i < _map.size(); ++i){
  295. for(unsigned e = 0; e < _map[i].size(); ++e){
  296. for(unsigned z = 0; z < _map[i][e].get_employment_vector().size(); ++z){
  297. if(_map[i][e].get_building().get_type() == 2)
  298. ++workers;
  299. else if(_map[i][e].get_building().get_type() != 2)
  300. ++jobs;
  301. cout << _map[i][e].get_employment_vector()[z].first << " " << _map[i][e].get_employment_vector()[z].second << endl;
  302. }
  303. }
  304. }
  305. cout << "Wind------------" << endl;
  306. for(unsigned i = 0; i < _map.size(); ++i){
  307. for(unsigned e = 0; e < _map[i].size(); ++e){
  308. if(_select.posx() == int(e) && _select.posy() == int(i))
  309. cout << PURPLE << _map[e][i].get_wind() << " " << _map[e][i].clear_color();
  310. else
  311. cout << _map[e][i].color_by_type() << _map[e][i].get_wind() << " " << _map[e][i].clear_color();
  312. }
  313. cout << endl;
  314. }
  315. cout << "Building time------------" << endl;
  316. for(unsigned i = 0; i < _map.size(); ++i){
  317. for(unsigned e = 0; e < _map[i].size(); ++e){
  318. if(_select.posx() == int(e) && _select.posy() == int(i))
  319. cout << PURPLE << _map[e][i].get_building_time() << " " << _map[e][i].clear_color();
  320. else
  321. cout << _map[e][i].color_by_building_time() << _map[e][i].get_building_time() << " " << _map[e][i].clear_color();
  322. }
  323. cout << endl;
  324. }
  325. cout << "jobs " << jobs << "\nworkers " << workers << endl;
  326. cout << "unemployment------" << endl;
  327. for(unsigned i = 0; i < _unemployment_vector.size(); ++i){
  328. cout << _unemployment_vector[i].first << " " << _unemployment_vector[i].second <<endl;
  329. }
  330. cout << "garbage: " << _waste << endl;
  331. }
  332. void city::set_cell(cell c){
  333. int destroy = 0;
  334. if(_map[_select.posx()][_select.posy()].get_building().get_type() != LAND){
  335. cout << "Do you want to destroy the building in that position?" << endl;
  336. cout << "1.- Yes (it'll cost 100 vakuoj)\n2.- No" << endl;
  337. _money -= 100;
  338. cin >> destroy;
  339. }
  340. if(destroy == 1 or
  341. _map[_select.posx()][_select.posy()].get_building().get_type() == LAND){
  342. _money -= c.get_building().get_cost();
  343. if(_map[_select.posx()][_select.posy()].get_building().get_type() == INDUSTRY or
  344. _map[_select.posx()][_select.posy()].get_building().get_type() == RESIDENTIAL or
  345. _map[_select.posx()][_select.posy()].get_building().get_type() == SHOPS)
  346. unemploy_cell( _select.posx(),_select.posy());
  347. _map[_select.posx()][_select.posy()] = c;
  348. if(c.get_building().get_type() == 2)
  349. _unemployment_vector.push_back(pair<int,int>(_select.posx(),_select.posy()));
  350. }
  351. }
  352. void city::set_pipe(){
  353. _map[_select.posx()][_select.posy()].set_pipe(true);
  354. }
  355. void city::flow_water(int i, int e){
  356. if(_map[i][e].get_water() > 0 && _map[i][e].has_pipe()){
  357. for(int o = 3; o > 0; --o){
  358. if((i - o) >= 0)
  359. _map[i - o][e].set_water(4 - o);
  360. if((e - o) >= 0)
  361. _map[i][e - o].set_water(4 - o);
  362. if((i + o) < _map[i].size())
  363. _map[i + o][e].set_water(4 - o);
  364. if((e + o) < _map[i].size())
  365. _map[i][e + o].set_water(4 - o);
  366. }
  367. }
  368. }
  369. void city::nextGeneration(){
  370. set_residentials(0);
  371. set_shops(0);
  372. set_industry(0);
  373. set_waste(0);
  374. _unemployment_vector.clear();
  375. for(unsigned i = 0; i < _map.size(); ++i){
  376. for(unsigned e = 0; e < _map.size(); ++e){
  377. _map[i][e].set_air_pollution(0); //Think better solution
  378. _map[i][e].set_electricity(0);
  379. _map[i][e].set_water(0);
  380. _map[i][e].set_traffic(0);
  381. }
  382. }
  383. vector<vector<cell>> new_field = _map;
  384. int wind = _wind;
  385. for(unsigned i = 0;i < _map.size(); ++i){
  386. for(unsigned e = 0;e < _map[i].size(); ++e){
  387. if(_map[i][e].get_building().get_type() == POWER_STATION)
  388. electricity(i,e);
  389. if(_map[i][e].get_building().get_type() == WATER_STATION)
  390. water(i,e);
  391. _map[i][e].set_access(road(i,e));
  392. ecosystem_pollution(new_field,i,e);
  393. //Count buildings
  394. if(_map[i][e].get_building().get_type() == RESIDENTIAL)
  395. ++_residentials;
  396. else if(_map[i][e].get_building().get_type() == INDUSTRY)
  397. ++_industry;
  398. else if(_map[i][e].get_building().get_type() == SHOPS)
  399. ++_shops;
  400. if(_map[i][e].get_building().get_type() == GARBAGE_INCINERATOR)
  401. _waste -= _map[i][e].get_building().get_waste();
  402. else
  403. _waste += _map[i][e].get_building().get_waste();
  404. }
  405. }
  406. for(unsigned i = 0; i < _map.size(); ++i){
  407. for(unsigned e = 0; e < _map[i].size(); ++e){
  408. if(_map[i][e].get_building().get_type() == RESIDENTIAL && _map[i][e].get_employment_vector().size() < 1
  409. && _map[i][e].has_needs_met())
  410. _unemployment_vector.push_back(pair<int,int>(i,e));
  411. if(_map[i][e].get_building().get_type() == RESIDENTIAL){
  412. set_residentials(get_residentials() + 1);
  413. }
  414. if((_map[i][e].get_building().get_type() == SHOPS ||
  415. _map[i][e].get_building().get_type() == RESIDENTIAL ||
  416. _map[i][e].get_building().get_type() == INDUSTRY)
  417. && int(_map[i][e].get_employment_vector().size()) < _map[i][e].get_building().get_max_people()){
  418. employ_cell(i,e);
  419. if(_map[i][e].get_building().get_type() == RESIDENTIAL)
  420. road_traffic(i,e);
  421. }
  422. _map[i][e].set_air_pollution(
  423. new_field[i][e].get_air_pollution());
  424. set_population(get_population() + population(i,e));
  425. if(_map[i][e].has_pipe())
  426. flow_water(i,e);
  427. if(_map[i][e].get_building_time() > 0)
  428. _map[i][e].set_building_time(_map[i][e].get_building_time() - 1);
  429. }
  430. }
  431. }
  432. void city::electricity(int i, int e){
  433. if(_map[i][e].get_building().get_type() == POWER_STATION){
  434. vector<cursor> vector_cell;
  435. cursor _cursor(i, e, _map.size(), _map[i].size());
  436. vector_cell.push_back(_cursor);
  437. int electricity = 0;
  438. while(vector_cell.size() > 0 && electricity >= 0){
  439. cursor _last_cursor(vector_cell[0]);
  440. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_electricity() == 0){
  441. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() !=
  442. LAND){
  443. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() ==
  444. POWER_STATION && _map[_last_cursor.posx()][_last_cursor.posy()].get_electricity()
  445. != -1){
  446. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_access() > 0){
  447. _map[_last_cursor.posx()][_last_cursor.posy()].set_electricity(-1);
  448. electricity += _map[_last_cursor.posx()][_last_cursor.posy()]
  449. .get_building().get_electricity_consumption();
  450. }
  451. if(_last_cursor.posx() < _last_cursor.limitx() - 1){
  452. cursor c = _last_cursor;
  453. c.right();
  454. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  455. insertion_not_repeated(c, vector_cell);
  456. }
  457. if(_last_cursor.posy() < _last_cursor.limity() - 1){
  458. cursor c = _last_cursor;
  459. c.down();
  460. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  461. insertion_not_repeated(c, vector_cell);
  462. }
  463. if(_last_cursor.posy() > 0){
  464. cursor c = _last_cursor;
  465. c.up();
  466. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  467. insertion_not_repeated(c, vector_cell);
  468. }
  469. if(_last_cursor.posx() > 0){
  470. cursor c = _last_cursor;
  471. c.left();
  472. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  473. insertion_not_repeated(c, vector_cell);
  474. }
  475. }else{
  476. if(electricity >= _map[_last_cursor.posx()][_last_cursor.posy()]
  477. .get_building().get_electricity_consumption()){
  478. electricity -= _map[_last_cursor.posx()][_last_cursor.posy()]
  479. .get_building().get_electricity_consumption();
  480. _map[_last_cursor.posx()][_last_cursor.posy()]
  481. .set_electricity(electricity);
  482. if(_last_cursor.posx() < _last_cursor.limitx() - 1){
  483. cursor c = _last_cursor;
  484. c.right();
  485. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  486. insertion_not_repeated(c, vector_cell);
  487. }
  488. if(_last_cursor.posy() < _last_cursor.limity() - 1){
  489. cursor c = _last_cursor;
  490. c.down();
  491. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  492. insertion_not_repeated(c, vector_cell);
  493. }
  494. if(_last_cursor.posy() > 0){
  495. cursor c = _last_cursor;
  496. c.up();
  497. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  498. insertion_not_repeated(c, vector_cell);
  499. }
  500. if(_last_cursor.posx() > 0){
  501. cursor c = _last_cursor;
  502. c.left();
  503. if(_map[c.posx()][c.posy()].get_electricity() == 0)
  504. insertion_not_repeated(c, vector_cell);
  505. }
  506. }
  507. }
  508. }
  509. }
  510. vector<cursor>::iterator it = vector_cell.begin();
  511. vector_cell.erase(it);
  512. if(electricity <= 0)
  513. electricity = -1;
  514. }
  515. }
  516. }
  517. void city::insertion_not_repeated(cursor c, vector<cursor>& v){
  518. bool inserted = false;
  519. for(size_t i = 0; i < v.size(); ++i)
  520. if(v[i].posy() == c.posy() && v[i].posx() == c.posx())
  521. inserted = true;
  522. if(!inserted)
  523. v.push_back(c);
  524. }
  525. void city::water(int i, int e){
  526. if(_map[i][e].get_building().get_type() == WATER_STATION){
  527. vector<cursor> vector_cell;
  528. cursor _cursor(i, e, _map.size(), _map[i].size());
  529. vector_cell.push_back(_cursor);
  530. int water = 0;
  531. while(vector_cell.size() > 0 && water >= 0){
  532. cursor _last_cursor(vector_cell[0]);
  533. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_water() == 0){
  534. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() != LAND){
  535. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() == WATER_STATION
  536. && _map[_last_cursor.posx()][_last_cursor.posy()].get_water() != -1){
  537. if(_map[_last_cursor.posx()][_last_cursor.posy()].get_access() > 0){
  538. _map[_last_cursor.posx()][_last_cursor.posy()].set_water(-1);
  539. water += _map[_last_cursor.posx()][_last_cursor.posy()]
  540. .get_building().get_water_consumption();
  541. }
  542. if(_last_cursor.posx() < _last_cursor.limitx() - 1){
  543. cursor c = _last_cursor;
  544. c.right();
  545. if(_map[c.posx()][c.posy()].get_water() == 0)
  546. vector_cell.push_back(c);
  547. }
  548. if(_last_cursor.posy() < _last_cursor.limity() - 1){
  549. cursor c = _last_cursor;
  550. c.down();
  551. if(_map[c.posx()][c.posy()].get_water() == 0)
  552. vector_cell.push_back(c);
  553. }
  554. if(_last_cursor.posy() > 0){
  555. cursor c = _last_cursor;
  556. c.up();
  557. if(_map[c.posx()][c.posy()].get_water() == 0)
  558. vector_cell.push_back(c);
  559. }
  560. if(_last_cursor.posx() > 0){
  561. cursor c = _last_cursor;
  562. c.left();
  563. if(_map[c.posx()][c.posy()].get_water() == 0)
  564. vector_cell.push_back(c);
  565. }
  566. }else{
  567. if(water >= _map[_last_cursor.posx()][_last_cursor.posy()]
  568. .get_building().get_water_consumption() && _map[_last_cursor.posx()][_last_cursor.posy()].has_pipe()){
  569. water -= _map[_last_cursor.posx()][_last_cursor.posy()]
  570. .get_building().get_water_consumption();
  571. _map[_last_cursor.posx()][_last_cursor.posy()]
  572. .set_water(water);
  573. if(_last_cursor.posx() < _last_cursor.limitx() - 1){
  574. cursor c = _last_cursor;
  575. c.right();
  576. if(_map[c.posx()][c.posy()].get_water() == 0)
  577. vector_cell.push_back(c);
  578. }
  579. if(_last_cursor.posy() < _last_cursor.limity() - 1){
  580. cursor c = _last_cursor;
  581. c.down();
  582. if(_map[c.posx()][c.posy()].get_water() == 0)
  583. vector_cell.push_back(c);
  584. }
  585. if(_last_cursor.posy() > 0){
  586. cursor c = _last_cursor;
  587. c.up();
  588. if(_map[c.posx()][c.posy()].get_water() == 0)
  589. vector_cell.push_back(c);
  590. }
  591. if(_last_cursor.posx() > 0){
  592. cursor c = _last_cursor;
  593. c.left();
  594. if(_map[c.posx()][c.posy()].get_water() == 0)
  595. vector_cell.push_back(c);
  596. }
  597. }
  598. }
  599. }
  600. }
  601. vector<cursor>::iterator it = vector_cell.begin();
  602. vector_cell.erase(it);
  603. if(water <= 0)
  604. water = -1;
  605. }
  606. }
  607. }
  608. void city::save(){
  609. json j;
  610. nlohmann::json map_tile;
  611. for(int i = 0; i < _size; ++i){
  612. stringstream ss;
  613. ss << i;
  614. vector<int> sf;
  615. nlohmann::json row;
  616. for(int e = 0; e < _size; ++e){
  617. row.push_back(_map[i][e].get_building().get_type());
  618. }
  619. map_tile.push_back(row);
  620. }
  621. j["map-tile"] = map_tile;
  622. nlohmann::json map_wind;
  623. for(int i = 0; i < _size; ++i){
  624. stringstream ss;
  625. ss << i;
  626. vector<int> sf;
  627. nlohmann::json row;
  628. for(int e = 0; e < _size; ++e){
  629. row.push_back(_map[i][e].get_wind());
  630. }
  631. map_wind.push_back(row);
  632. }
  633. j["map-wind"] = map_wind;
  634. nlohmann::json map_building_time;
  635. for(int i = 0; i < _size; ++i){
  636. stringstream ss;
  637. ss << i;
  638. vector<double> sf;
  639. nlohmann::json row;
  640. for(int e = 0; e < _size; ++e){
  641. row.push_back(_map[i][e].get_building_time());
  642. }
  643. map_building_time.push_back(row);
  644. }
  645. j["map-building-time"] = map_building_time;
  646. j["money"] = _money;
  647. j["time"] = _time;
  648. j["size"] = _size;
  649. j["population"] = _population;
  650. j["loans"] = _possible_loans.size();
  651. for(unsigned e = 0; e < _possible_loans.size(); ++e){
  652. stringstream ss;
  653. ss << e;
  654. j["possible-loan" + ss.str() + "-description"] = _possible_loans[e].get_description();
  655. j["possible-loan" + ss.str() + "-money"] = _possible_loans[e].get_money();
  656. j["possible-loan" + ss.str() + "-months"] = _possible_loans[e].get_months();
  657. j["possible-loan" + ss.str() + "-installment"] = _possible_loans[e].get_installment();
  658. }
  659. j["asked-loans"] = _asked_out_loans.size();
  660. for(unsigned e = 0; e < _asked_out_loans.size(); ++e){
  661. stringstream ss;
  662. ss << e;
  663. j["asked-loan" + ss.str() + "-description"] = _asked_out_loans[e].get_description();
  664. j["asked-loan" + ss.str() + "-money"] = _asked_out_loans[e].get_money();
  665. j["asked-loan" + ss.str() + "-months"] = _asked_out_loans[e].get_months();
  666. j["asked-loan" + ss.str() + "-installment"] = _asked_out_loans[e].get_installment();
  667. }
  668. std::ofstream out(_name + ".json");
  669. out << j.dump() << endl;
  670. out.close();
  671. }
  672. void city::create(){
  673. random_device rd;
  674. default_random_engine eng(rd());
  675. uniform_int_distribution<int> wind_value_distr(0, 20);
  676. _wind = wind_value_distr(eng);
  677. uniform_int_distribution<int> wind_variation_distr(-1, 1);
  678. int wind = _wind;
  679. for(int i = 0; i < _size; ++i){
  680. _map.push_back(vector<cell>());
  681. for(int e = 0; e < _size; ++e){
  682. _map[i].push_back(cell());
  683. if(i)
  684. wind = _map[i - 1][e].get_wind();
  685. _map[i][e].set_wind(wind + wind_variation_distr(eng));
  686. _map[i][e].set_building_time(0);
  687. }
  688. }
  689. _buildings = load_buildings();
  690. _possible_loans.push_back(loan("Good loan", 10000, 12, 10000));
  691. }
  692. void city::load(){
  693. std::ifstream in(_name + ".json");
  694. if(in){
  695. json j = json::parse(in);
  696. _map = vector<vector<cell>>();
  697. _size = j.at("map-tile").size();
  698. _select = cursor(_select.posx(), _select.posy(), _size, _size);
  699. _buildings = load_buildings();
  700. for(int i = 0; i < _size; ++i){
  701. vector<int> sf;
  702. j.at("map-tile").at(i).get_to(sf);
  703. vector<cell> vc;
  704. for(int e = 0; e < _size; ++e){
  705. vc.push_back( cell(_buildings[sf[e]]) );
  706. if(sf[e] == 2)
  707. _unemployment_vector.push_back(pair<int,int>(i,e));
  708. }
  709. _map.push_back(vc);
  710. }
  711. for(int i = 0; i < _size; ++i){
  712. vector<int> sf;
  713. j.at("map-wind").at(i).get_to(sf);
  714. vector<cell> vc;
  715. for(int e = 0; e < _size; ++e){
  716. _map[i][e].set_wind(sf[e]);
  717. }
  718. }
  719. for(int i = 0; i < _size; ++i){
  720. vector<double> bt;
  721. j.at("map-building-time").at(i).get_to(bt);
  722. vector<cell> vc;
  723. for(int e = 0; e < _size; ++e){
  724. _map[i][e].set_building_time(bt[e]);
  725. }
  726. }
  727. in.close();
  728. _possible_loans.clear();
  729. for(unsigned e = 0; e < j.at("loans"); ++e){
  730. stringstream ss;
  731. ss << e;
  732. loan n(j.at("possible-loan" + ss.str() + "-description"),
  733. j.at("possible-loan" + ss.str() + "-money"),
  734. j.at("possible-loan" + ss.str() + "-months"),
  735. j.at("possible-loan" + ss.str() + "-installment"));
  736. _possible_loans.push_back(n);
  737. }
  738. for(unsigned e = 0; e < j.at("asked-loans"); ++e){
  739. stringstream ss;
  740. ss << e;
  741. loan n(j.at("asked-loan" + ss.str() + "-description"),
  742. j.at("asked-loan" + ss.str() + "-money"),
  743. j.at("asked-loan" + ss.str() + "-months"),
  744. j.at("asked-loan" + ss.str() + "-installment"));
  745. _asked_out_loans.push_back(n);
  746. }
  747. j.at("money").get_to(_money);
  748. j.at("time").get_to(_time);
  749. j.at("size").get_to(_size);
  750. j.at("population").get_to(_population);
  751. }
  752. }
  753. void city::ecosystem_pollution(vector<vector<cell>>& new_field, int i, int e){
  754. int base_pollution = _map[i][e].get_building().get_air_pollution();
  755. int top_limit = i + base_pollution + 1;
  756. int bottom_limit = i - base_pollution - 1;
  757. int left_limit = e - base_pollution - 1;
  758. int right_limit = e + base_pollution + 1;
  759. int size = _map.size() - 1;
  760. if(bottom_limit < 0)
  761. bottom_limit = 0;
  762. if(left_limit < 0)
  763. left_limit = 0;
  764. if(right_limit >= size)
  765. right_limit = size;
  766. if(top_limit >= size)
  767. top_limit = size;
  768. if(base_pollution > 1){
  769. for(int y = bottom_limit; y <= top_limit; ++y){
  770. for(int x = left_limit; x <= right_limit; ++x){
  771. int calculated_pollution = base_pollution - (abs(y - i) + abs(x - e));
  772. if(calculated_pollution > 0)
  773. new_field[y][x].set_air_pollution(
  774. new_field[y][x].get_air_pollution() + calculated_pollution
  775. );
  776. }
  777. }
  778. }else
  779. new_field[i][e].set_air_pollution(
  780. new_field[i][e].get_air_pollution() + base_pollution);
  781. }
  782. int city::population(int i, int e){
  783. if(_map[i][e].get_building().get_type() == RESIDENTIAL and
  784. _map[i][e].get_electricity() > 0 and _map[i][e].get_access() > 0)
  785. return _buildings[RESIDENTIAL].get_max_people();
  786. else
  787. return 0;
  788. }
  789. int city::road(int i, int e){
  790. int result = 0;
  791. int size = _map.size() - 1;
  792. switch(_map[i][e].get_building().get_type()){
  793. case LAND:{
  794. result = 0;
  795. };break;
  796. case ROAD:{
  797. result = 4;
  798. };break;
  799. case RESIDENTIAL:{
  800. if(i != size and _map[i+1][e].get_access() != 0)
  801. result = _map[i+1][e].get_access() - 1;
  802. if(e != size and _map[i][e+1].get_access() > result)
  803. result = _map[i][e+1].get_access() - 1;
  804. if(i != 0 and _map[i-1][e].get_access() > result)
  805. result = _map[i-1][e].get_access() - 1;
  806. if(e != 0 and _map[i][e-1].get_access() > result)
  807. result = _map[i][e-1].get_access() - 1;
  808. };break;
  809. case POWER_STATION:{
  810. if(i != size and _map[i+1][e].get_access() != 0)
  811. result = _map[i+1][e].get_access() - 1;
  812. if(e != size and _map[i][e+1].get_access() > result)
  813. result = _map[i][e+1].get_access() - 1;
  814. if(i != 0 and _map[i-1][e].get_access() > result)
  815. result = _map[i-1][e].get_access() - 1;
  816. if(e != 0 and _map[i][e-1].get_access() > result)
  817. result = _map[i][e-1].get_access() - 1;
  818. };break;
  819. case SHOPS:{
  820. if(i != size and _map[i+1][e].get_access() != 0)
  821. result = _map[i+1][e].get_access() - 1;
  822. if(e != size and _map[i][e+1].get_access() > result)
  823. result = _map[i][e+1].get_access() - 1;
  824. if(i != 0 and _map[i-1][e].get_access() > result)
  825. result = _map[i-1][e].get_access() - 1;
  826. if(e != 0 and _map[i][e-1].get_access() > result)
  827. result = _map[i][e-1].get_access() - 1;
  828. };break;
  829. case INDUSTRY:{
  830. if(i != size and _map[i+1][e].get_access() != 0)
  831. result = _map[i+1][e].get_access() - 1;
  832. if(e != size and _map[i][e+1].get_access() > result)
  833. result = _map[i][e+1].get_access() - 1;
  834. if(i != 0 and _map[i-1][e].get_access() > result)
  835. result = _map[i-1][e].get_access() - 1;
  836. if(e != 0 and _map[i][e-1].get_access() > result)
  837. result = _map[i][e-1].get_access() - 1;
  838. };break;
  839. case WATER_STATION:{
  840. if(i != size and _map[i+1][e].get_access() != 0)
  841. result = _map[i+1][e].get_access() - 1;
  842. if(e != size and _map[i][e+1].get_access() > result)
  843. result = _map[i][e+1].get_access() - 1;
  844. if(i != 0 and _map[i-1][e].get_access() > result)
  845. result = _map[i-1][e].get_access() - 1;
  846. if(e != 0 and _map[i][e-1].get_access() > result)
  847. result = _map[i][e-1].get_access() - 1;
  848. };break;
  849. default: result = 0;break;
  850. }
  851. return result;
  852. }
  853. int city::income(){
  854. int result = 0;
  855. int road_costs = 0;
  856. int electricity_production_costs = 0;
  857. float loans_debt = 0;
  858. for(unsigned i = 0; i < _map.size(); ++i){
  859. for(unsigned e = 0; e < _map[i].size(); ++e){
  860. if(_map[i][e].get_building().get_type() == RESIDENTIAL and
  861. _map[i][e].get_electricity() > 0 and _map[i][e].get_access() > 0)
  862. result += 2;
  863. else if(_map[i][e].get_building().get_type() == ROAD)
  864. road_costs += 1;
  865. else if(_map[i][e].get_building().get_type() == POWER_STATION)
  866. electricity_production_costs += 5;
  867. }
  868. }
  869. for(unsigned i = 0; i < _asked_out_loans.size(); ++i){
  870. loans_debt += _asked_out_loans[i].get_installment();
  871. _asked_out_loans[i].set_months(_asked_out_loans[i].get_months() - 1);
  872. _asked_out_loans[i].set_money(_asked_out_loans[i].get_money() - _asked_out_loans[i].get_installment());
  873. if(_asked_out_loans[i].get_months() == 0)
  874. _asked_out_loans.erase(_asked_out_loans.begin() + i);
  875. }
  876. cout << "-------------------" << endl;
  877. cout << "Monthly review" << endl;
  878. cout << "Income: " << result << endl;
  879. cout << "Electricity production costs: " << electricity_production_costs << endl;
  880. cout << "Road costs: " << road_costs << endl;
  881. if(_asked_out_loans.size() > 0)
  882. cout << "Loans installment: " << loans_debt << endl;
  883. cout << "-------------------" << endl;
  884. result -= road_costs + electricity_production_costs;
  885. return result;
  886. }
  887. int city::get_needed_residentials(){
  888. float sum = (2/3.0) * _industry + (1/3.0) * _shops;
  889. return (int) sum;
  890. }
  891. int city::get_needed_industry(){
  892. float sum = 3 * _industry - _shops;
  893. sum = sum / 2;
  894. return (int) sum;
  895. }
  896. int city::get_needed_shops(){
  897. float sum = 3 * _residentials - 2 * _industry;
  898. return (int) sum;
  899. }
  900. void city::get_loan(){
  901. unsigned e;
  902. for(unsigned i = 0; i < _possible_loans.size(); ++i){
  903. cout << "loan " << i <<endl;
  904. cout << "description " << _possible_loans[i].get_description() << endl;
  905. cout << "money " << _possible_loans[i].get_money() << endl;
  906. cout << "months " << _possible_loans[i].get_months() << endl;
  907. cout << "installment " << _possible_loans[i].get_installment() << endl;
  908. cout << "--------------------------------------" << endl;
  909. }
  910. cout << "loan number" << endl;
  911. cin >> e;
  912. if(e < _possible_loans.size()){
  913. _money += _possible_loans[e].get_money();
  914. _asked_out_loans.push_back(_possible_loans[e]);
  915. _possible_loans.erase(_possible_loans.begin() + e);
  916. }
  917. }