12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049 |
- #include "city.h"
- #include "cell.h"
- #include "building.h"
- #include "json.hpp"
- #include "loan.h"
- #include <iostream>
- #include <set>
- #include <fstream>
- #include <sstream>
- #include <random>
- using namespace std;
- using json = nlohmann::json;
- const std::string PURPLE = "\033[35m";
- void cursor::up(){ if(y > 0) --y;}
- void cursor::down(){ if(y < (limit_y - 1)) ++y; }
- void cursor::left(){ if(x > 0) --x; }
- void cursor::right(){ if(x < (limit_x - 1)) ++x; }
- int cursor::posx() const{ return x; }
- int cursor::posy() const{ return y; }
- int cursor::limitx() const{ return limit_x; }
- int cursor::limity() const{ return limit_y; }
- void city::unemploy_cell(int x, int y){
- vector<pair<int, int>> employment_vector = _map[x][y].get_employment_vector();
- vector<pair<int, int>>::iterator begin = employment_vector.begin();
- while(begin != employment_vector.end()){
- _map[(*begin).first][(*begin).second].delete_employment(x,y);
- if(_map[(*begin).first][(*begin).second].get_building().get_type() == RESIDENTIAL)
- _unemployment_vector.push_back(pair<int,int>((*begin).first,(*begin).second));
-
- begin++;
- }
- _map[x][y].clear_employment();
- if(_map[x][y].get_building().get_type() == RESIDENTIAL)
- _unemployment_vector.push_back(pair<int,int>(x,y));
- }
- void city::employ_cell(int x, int y){
- if(_unemployment_vector.size() > 0 && (_map[x][y].get_building().get_type() == INDUSTRY || _map[x][y].get_building().get_type() == SHOPS)){
- pair<int, int> c2 = _unemployment_vector[0];
- _map[x][y].set_employment(c2.first, c2.second);
- _map[c2.first][c2.second].set_employment(x, y);
- _unemployment_vector.erase(_unemployment_vector.begin());
- }
- }
- void city::road_traffic(int i, int e){
- vector<pair<int,int>> employment = _map[i][e].get_employment_vector();
- for(size_t x = 0; x < employment.size(); ++x){
- vector<pair<int,int>> route = smaller_route(i, e, employment[x].first, employment[x].second);
-
- for(size_t r = 0; r < route.size(); ++r){
- _map[route[r].first][route[r].second].set_traffic(_map[route[r].first][route[r].second].get_traffic() + 1);
- }
- }
- }
- /*
- * direction:
- * 0: up
- * 1: right
- * 2: down
- * 3: left
- */
- pair<int,int> city::get_near_road(int i, int e){
- int direction = 0;
- int local = _map[i][e].get_access();
- if(e > 0 && _map[i][e - 1].get_access() > local)
- direction = 3;
- else if(i > 0 && _map[i - 1][e].get_access() > local)
- direction = 0;
- else if(e < int(_map[i].size()) && _map[i][e + 1].get_access() > local)
- direction = 1;
- else if(i < int(_map.size()) && _map[i + 1][e].get_access() > local)
- direction = 2;
- switch(direction){
- case 0:{
- int x = i, y = e;
- while(x > 0 && _map[x][y].get_building().get_type() != ROAD){
- --x;
- }
- return make_pair(x,y);
- };break;
- case 1:{
- int x = i, y = e;
- while(y < int(_map[x].size()) && _map[x][y].get_building().get_type() != ROAD){
- ++y;
- }
- return make_pair(x,y);
- };break;
- case 2:{
- int x = i, y = e;
- while(x < int(_map.size()) && _map[x][y].get_building().get_type() != ROAD){
- ++x;
- }
- return make_pair(x,y);
- };break;
- case 3:{
- int x = i, y = e;
- while(y > 0 && _map[x][y].get_building().get_type() != ROAD){
- --y;
- }
- return make_pair(x,y);
- };break;
- }
- return make_pair(-1,-1);
- }
- int city::positions_to_node(int i, int e){
- return i * _map.size() + e;
- }
- void city::pay_bigger_city(){
- int previous_size = _size;
-
- if(_money >= (_size + 1) * 10){
- _size += 1;
- vector<cell> c(_size, cell());
- _money -= _size * 10;
- for(int i = 0; i < previous_size; ++i){
- _map[i].push_back(cell());
- }
- _map.push_back(c);
-
- }
- }
- pair<int,int> city::node_to_positions(int node) {
- return make_pair(node / _map.size(), node % _map.size());
- }
- vector<pair<int,int>> city::dijkstra(int x, int y, int dest_x, int dest_y) {
- int max = _map[x].size() * _map.size();
- int n = max;
- int start_node = positions_to_node(x,y);
- int end_node = positions_to_node(dest_x,dest_y);
- int cost[max][max], distance[max], pred[max];
- int visited[max], count, min_distance, next_node = -1, i, j;
- for(i = 0;i < n; i++){
- for(j = 0; j < n ; j++){
- pair<int, int> origin = node_to_positions(i);
- pair<int, int> destination = node_to_positions(j);
- cost[i][j] = int(INFINITY);
- if(i == j)
- cost[i][j] = 0;
- else{
- int z = 0;
- bool near = false;
- if(origin.first + 1 == destination.first)
- --z;
- if(origin.second + 1 == destination.second)
- --z;
- if(origin.first == destination.first){
- near = true;
- ++z;
- }
- if(origin.second == destination.second){
- ++z;
- near = true;
- }
- if(origin.first -1 == destination.first)
- --z;
- if(origin.second - 1 == destination.second)
- --z;
- if(z == 0 && near && _map[origin.first][origin.second].get_building().get_type() == ROAD && _map[destination.first][destination.second].get_building().get_type() == ROAD){
- cost[i][j] = 1;
- }else{
- cost[i][j] = int(INFINITY);
- }
- }
- }
- }
- for(i = 0; i < n; i++) {
- distance[i] = cost[start_node][i];
- pred[i] = start_node;
- visited[i] = 0;
- }
- pair<int, int> previous_node;
- distance[start_node] = 0;
- visited[start_node] = 1;
- count = 1;
- while(count < n - 1) {
- min_distance = int(INFINITY);
- for(i = 0; i < n; i++) {
- //TODO: Match differences between direction and one way road
- if(i > 0 && _map[node_to_positions(i).first][node_to_positions(i).second].get_building().get_type() == ONE_WAY_ROAD) {
- previous_node = node_to_positions(pred[i - 1]);
- pair<int,int> prev_positions = previous_node;
- pair<int,int> next_positions = node_to_positions(i);
- int x = prev_positions.first - next_positions.first;
- int y = prev_positions.second - next_positions.second;
- int direction = _map[node_to_positions(i).first][node_to_positions(i).second].get_direction();
- if( !(x > 0 && direction == 1) || !(x < 0 && direction == 2) || !(y < 0 && direction == 3) || !(y > 0 && direction == 4)){
- distance[i] = int(INFINITY);
- }
- }
- if(distance[i] < min_distance && !visited[i]) {
- min_distance = distance[i];
- next_node = i;
- }
- }
- if(next_node != -1){
- visited[next_node] = 1;
- for(i = 0; i < n; i++)
- if(!visited[i])
- if(min_distance + cost[next_node][i] < distance[i]) {
- distance[i] = min_distance + cost[next_node][i];
- pred[i] = next_node;
- }
- }
- count++;
- }
- vector<pair<int,int>> v;
- if(distance[end_node] != int(INFINITY)){
- int temp_node = end_node;
- pair<int,int> p = node_to_positions(temp_node);
- do {
- temp_node = pred[temp_node];
- p = node_to_positions(temp_node);
- v.push_back(p);
- }while(temp_node != start_node);
- }
- return v;
- }
- vector<pair<int,int>> city::smaller_route(int origin_x, int origin_y, int destination_x, int destination_y){
- pair<int, int> origin = get_near_road(origin_x, origin_y);
- pair<int, int> destination = get_near_road(destination_x, destination_y);
- return dijkstra(origin.first, origin.second, destination.first, destination.second);
- }
- city::city(const string& name, int money, int size): _name(name),
- _money(money), _size(size), _time(32), _population(0), _residentials(0), _shops(0), _industry(0),
- _select(cursor(0, 0, size, size)), _waste(0){
- ifstream in(_name + ".json");
- if(in){
- try{
- load();
- }catch(...){ create(); }
- }else{
- create();
- }
- }
- void city::print(){
- cout << "\nType------------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_building().get_type() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_type() << _map[e][i].get_building().get_type() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "Electricity-------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_electricity() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_electricity() << _map[e][i].get_electricity() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "Water-------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_water() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_water() << _map[e][i].get_water() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "Pollution---------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_air_pollution() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_pollution() << _map[e][i].get_air_pollution() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "Access------------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_access() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_access() << _map[e][i].get_access() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "Traffic------------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_traffic() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_traffic() << _map[e][i].get_traffic() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "working people------------" << endl;
- int workers = 0;
- int jobs = 0;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- for(unsigned z = 0; z < _map[i][e].get_employment_vector().size(); ++z){
- if(_map[i][e].get_building().get_type() == 2)
- ++workers;
- else if(_map[i][e].get_building().get_type() != 2)
- ++jobs;
- cout << _map[i][e].get_employment_vector()[z].first << " " << _map[i][e].get_employment_vector()[z].second << endl;
- }
- }
- }
-
- cout << "Wind------------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_wind() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_type() << _map[e][i].get_wind() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "Building time------------" << endl;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_select.posx() == int(e) && _select.posy() == int(i))
- cout << PURPLE << _map[e][i].get_building_time() << " " << _map[e][i].clear_color();
- else
- cout << _map[e][i].color_by_building_time() << _map[e][i].get_building_time() << " " << _map[e][i].clear_color();
- }
- cout << endl;
- }
- cout << "jobs " << jobs << "\nworkers " << workers << endl;
- cout << "unemployment------" << endl;
- for(unsigned i = 0; i < _unemployment_vector.size(); ++i){
- cout << _unemployment_vector[i].first << " " << _unemployment_vector[i].second <<endl;
- }
- cout << "garbage: " << _waste << endl;
- }
- void city::set_cell(cell c){
- int destroy = 0;
- if(_map[_select.posx()][_select.posy()].get_building().get_type() != LAND){
- cout << "Do you want to destroy the building in that position?" << endl;
- cout << "1.- Yes (it'll cost 100 vakuoj)\n2.- No" << endl;
- _money -= 100;
- cin >> destroy;
- }
- if(destroy == 1 or
- _map[_select.posx()][_select.posy()].get_building().get_type() == LAND){
- _money -= c.get_building().get_cost();
- if(_map[_select.posx()][_select.posy()].get_building().get_type() == INDUSTRY or
- _map[_select.posx()][_select.posy()].get_building().get_type() == RESIDENTIAL or
- _map[_select.posx()][_select.posy()].get_building().get_type() == SHOPS)
- unemploy_cell( _select.posx(),_select.posy());
- _map[_select.posx()][_select.posy()] = c;
- if(c.get_building().get_type() == 2)
- _unemployment_vector.push_back(pair<int,int>(_select.posx(),_select.posy()));
- }
- }
- void city::set_pipe(){
- _map[_select.posx()][_select.posy()].set_pipe(true);
- }
- void city::flow_water(int i, int e){
- if(_map[i][e].get_water() > 0 && _map[i][e].has_pipe()){
- for(int o = 3; o > 0; --o){
- if((i - o) >= 0)
- _map[i - o][e].set_water(4 - o);
- if((e - o) >= 0)
- _map[i][e - o].set_water(4 - o);
- if((i + o) < _map[i].size())
- _map[i + o][e].set_water(4 - o);
- if((e + o) < _map[i].size())
- _map[i][e + o].set_water(4 - o);
- }
- }
- }
- void city::nextGeneration(){
- set_residentials(0);
- set_shops(0);
- set_industry(0);
- set_waste(0);
- _unemployment_vector.clear();
-
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map.size(); ++e){
- _map[i][e].set_air_pollution(0); //Think better solution
- _map[i][e].set_electricity(0);
- _map[i][e].set_water(0);
- _map[i][e].set_traffic(0);
- }
- }
- vector<vector<cell>> new_field = _map;
- int wind = _wind;
- for(unsigned i = 0;i < _map.size(); ++i){
-
- for(unsigned e = 0;e < _map[i].size(); ++e){
-
- if(_map[i][e].get_building().get_type() == POWER_STATION)
- electricity(i,e);
- if(_map[i][e].get_building().get_type() == WATER_STATION)
- water(i,e);
-
- _map[i][e].set_access(road(i,e));
- ecosystem_pollution(new_field,i,e);
- //Count buildings
- if(_map[i][e].get_building().get_type() == RESIDENTIAL)
- ++_residentials;
- else if(_map[i][e].get_building().get_type() == INDUSTRY)
- ++_industry;
- else if(_map[i][e].get_building().get_type() == SHOPS)
- ++_shops;
-
- if(_map[i][e].get_building().get_type() == GARBAGE_INCINERATOR)
- _waste -= _map[i][e].get_building().get_waste();
- else
- _waste += _map[i][e].get_building().get_waste();
- }
- }
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_map[i][e].get_building().get_type() == RESIDENTIAL && _map[i][e].get_employment_vector().size() < 1
- && _map[i][e].has_needs_met())
- _unemployment_vector.push_back(pair<int,int>(i,e));
- if(_map[i][e].get_building().get_type() == RESIDENTIAL){
- set_residentials(get_residentials() + 1);
- }
- if((_map[i][e].get_building().get_type() == SHOPS ||
- _map[i][e].get_building().get_type() == RESIDENTIAL ||
- _map[i][e].get_building().get_type() == INDUSTRY)
- && int(_map[i][e].get_employment_vector().size()) < _map[i][e].get_building().get_max_people()){
- employ_cell(i,e);
- if(_map[i][e].get_building().get_type() == RESIDENTIAL)
- road_traffic(i,e);
- }
- _map[i][e].set_air_pollution(
- new_field[i][e].get_air_pollution());
- set_population(get_population() + population(i,e));
- if(_map[i][e].has_pipe())
- flow_water(i,e);
-
- if(_map[i][e].get_building_time() > 0)
- _map[i][e].set_building_time(_map[i][e].get_building_time() - 1);
- }
- }
- }
- void city::electricity(int i, int e){
- if(_map[i][e].get_building().get_type() == POWER_STATION){
- vector<cursor> vector_cell;
-
- cursor _cursor(i, e, _map.size(), _map[i].size());
- vector_cell.push_back(_cursor);
- int electricity = 0;
- while(vector_cell.size() > 0 && electricity >= 0){
- cursor _last_cursor(vector_cell[0]);
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_electricity() == 0){
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() !=
- LAND){
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() ==
- POWER_STATION && _map[_last_cursor.posx()][_last_cursor.posy()].get_electricity()
- != -1){
-
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_access() > 0){
- _map[_last_cursor.posx()][_last_cursor.posy()].set_electricity(-1);
- electricity += _map[_last_cursor.posx()][_last_cursor.posy()]
- .get_building().get_electricity_consumption();
- }
- if(_last_cursor.posx() < _last_cursor.limitx() - 1){
- cursor c = _last_cursor;
- c.right();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
-
- }
- if(_last_cursor.posy() < _last_cursor.limity() - 1){
- cursor c = _last_cursor;
- c.down();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
- }
- if(_last_cursor.posy() > 0){
- cursor c = _last_cursor;
- c.up();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
- }
- if(_last_cursor.posx() > 0){
- cursor c = _last_cursor;
- c.left();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
- }
- }else{
- if(electricity >= _map[_last_cursor.posx()][_last_cursor.posy()]
- .get_building().get_electricity_consumption()){
- electricity -= _map[_last_cursor.posx()][_last_cursor.posy()]
- .get_building().get_electricity_consumption();
- _map[_last_cursor.posx()][_last_cursor.posy()]
- .set_electricity(electricity);
- if(_last_cursor.posx() < _last_cursor.limitx() - 1){
- cursor c = _last_cursor;
- c.right();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
-
- }
- if(_last_cursor.posy() < _last_cursor.limity() - 1){
- cursor c = _last_cursor;
- c.down();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
- }
- if(_last_cursor.posy() > 0){
- cursor c = _last_cursor;
- c.up();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
- }
- if(_last_cursor.posx() > 0){
- cursor c = _last_cursor;
- c.left();
- if(_map[c.posx()][c.posy()].get_electricity() == 0)
- insertion_not_repeated(c, vector_cell);
- }
- }
- }
-
- }
- }
- vector<cursor>::iterator it = vector_cell.begin();
- vector_cell.erase(it);
- if(electricity <= 0)
- electricity = -1;
- }
- }
- }
- void city::insertion_not_repeated(cursor c, vector<cursor>& v){
- bool inserted = false;
- for(size_t i = 0; i < v.size(); ++i)
- if(v[i].posy() == c.posy() && v[i].posx() == c.posx())
- inserted = true;
- if(!inserted)
- v.push_back(c);
- }
- void city::water(int i, int e){
- if(_map[i][e].get_building().get_type() == WATER_STATION){
- vector<cursor> vector_cell;
- cursor _cursor(i, e, _map.size(), _map[i].size());
- vector_cell.push_back(_cursor);
- int water = 0;
- while(vector_cell.size() > 0 && water >= 0){
- cursor _last_cursor(vector_cell[0]);
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_water() == 0){
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() != LAND){
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_building().get_type() == WATER_STATION
- && _map[_last_cursor.posx()][_last_cursor.posy()].get_water() != -1){
-
- if(_map[_last_cursor.posx()][_last_cursor.posy()].get_access() > 0){
- _map[_last_cursor.posx()][_last_cursor.posy()].set_water(-1);
- water += _map[_last_cursor.posx()][_last_cursor.posy()]
- .get_building().get_water_consumption();
- }
- if(_last_cursor.posx() < _last_cursor.limitx() - 1){
- cursor c = _last_cursor;
- c.right();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- if(_last_cursor.posy() < _last_cursor.limity() - 1){
- cursor c = _last_cursor;
- c.down();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- if(_last_cursor.posy() > 0){
- cursor c = _last_cursor;
- c.up();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- if(_last_cursor.posx() > 0){
- cursor c = _last_cursor;
- c.left();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- }else{
- if(water >= _map[_last_cursor.posx()][_last_cursor.posy()]
- .get_building().get_water_consumption() && _map[_last_cursor.posx()][_last_cursor.posy()].has_pipe()){
- water -= _map[_last_cursor.posx()][_last_cursor.posy()]
- .get_building().get_water_consumption();
- _map[_last_cursor.posx()][_last_cursor.posy()]
- .set_water(water);
- if(_last_cursor.posx() < _last_cursor.limitx() - 1){
- cursor c = _last_cursor;
- c.right();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- if(_last_cursor.posy() < _last_cursor.limity() - 1){
- cursor c = _last_cursor;
- c.down();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- if(_last_cursor.posy() > 0){
- cursor c = _last_cursor;
- c.up();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- if(_last_cursor.posx() > 0){
- cursor c = _last_cursor;
- c.left();
- if(_map[c.posx()][c.posy()].get_water() == 0)
- vector_cell.push_back(c);
- }
- }
- }
- }
- }
- vector<cursor>::iterator it = vector_cell.begin();
- vector_cell.erase(it);
- if(water <= 0)
- water = -1;
- }
- }
- }
- void city::save(){
- json j;
- nlohmann::json map_tile;
- for(int i = 0; i < _size; ++i){
- stringstream ss;
- ss << i;
- vector<int> sf;
- nlohmann::json row;
- for(int e = 0; e < _size; ++e){
- row.push_back(_map[i][e].get_building().get_type());
- }
- map_tile.push_back(row);
- }
- j["map-tile"] = map_tile;
- nlohmann::json map_wind;
- for(int i = 0; i < _size; ++i){
- stringstream ss;
- ss << i;
- vector<int> sf;
- nlohmann::json row;
- for(int e = 0; e < _size; ++e){
- row.push_back(_map[i][e].get_wind());
- }
- map_wind.push_back(row);
- }
- j["map-wind"] = map_wind;
-
- nlohmann::json map_building_time;
- for(int i = 0; i < _size; ++i){
- stringstream ss;
- ss << i;
- vector<double> sf;
- nlohmann::json row;
- for(int e = 0; e < _size; ++e){
- row.push_back(_map[i][e].get_building_time());
- }
- map_building_time.push_back(row);
- }
- j["map-building-time"] = map_building_time;
-
-
- j["money"] = _money;
- j["time"] = _time;
- j["size"] = _size;
- j["population"] = _population;
- j["loans"] = _possible_loans.size();
- for(unsigned e = 0; e < _possible_loans.size(); ++e){
- stringstream ss;
- ss << e;
- j["possible-loan" + ss.str() + "-description"] = _possible_loans[e].get_description();
- j["possible-loan" + ss.str() + "-money"] = _possible_loans[e].get_money();
- j["possible-loan" + ss.str() + "-months"] = _possible_loans[e].get_months();
- j["possible-loan" + ss.str() + "-installment"] = _possible_loans[e].get_installment();
- }
- j["asked-loans"] = _asked_out_loans.size();
- for(unsigned e = 0; e < _asked_out_loans.size(); ++e){
- stringstream ss;
- ss << e;
- j["asked-loan" + ss.str() + "-description"] = _asked_out_loans[e].get_description();
- j["asked-loan" + ss.str() + "-money"] = _asked_out_loans[e].get_money();
- j["asked-loan" + ss.str() + "-months"] = _asked_out_loans[e].get_months();
- j["asked-loan" + ss.str() + "-installment"] = _asked_out_loans[e].get_installment();
- }
- std::ofstream out(_name + ".json");
- out << j.dump() << endl;
- out.close();
- }
- void city::create(){
- random_device rd;
- default_random_engine eng(rd());
- uniform_int_distribution<int> wind_value_distr(0, 20);
- _wind = wind_value_distr(eng);
-
- uniform_int_distribution<int> wind_variation_distr(-1, 1);
-
- int wind = _wind;
- for(int i = 0; i < _size; ++i){
- _map.push_back(vector<cell>());
- for(int e = 0; e < _size; ++e){
- _map[i].push_back(cell());
- if(i)
- wind = _map[i - 1][e].get_wind();
- _map[i][e].set_wind(wind + wind_variation_distr(eng));
- _map[i][e].set_building_time(0);
- }
- }
- _buildings = load_buildings();
- _possible_loans.push_back(loan("Good loan", 10000, 12, 10000));
- }
- void city::load(){
- std::ifstream in(_name + ".json");
- if(in){
- json j = json::parse(in);
- _map = vector<vector<cell>>();
- _size = j.at("map-tile").size();
- _select = cursor(_select.posx(), _select.posy(), _size, _size);
- _buildings = load_buildings();
- for(int i = 0; i < _size; ++i){
- vector<int> sf;
- j.at("map-tile").at(i).get_to(sf);
- vector<cell> vc;
- for(int e = 0; e < _size; ++e){
- vc.push_back( cell(_buildings[sf[e]]) );
- if(sf[e] == 2)
- _unemployment_vector.push_back(pair<int,int>(i,e));
- }
- _map.push_back(vc);
- }
-
- for(int i = 0; i < _size; ++i){
- vector<int> sf;
- j.at("map-wind").at(i).get_to(sf);
- vector<cell> vc;
- for(int e = 0; e < _size; ++e){
- _map[i][e].set_wind(sf[e]);
- }
- }
-
- for(int i = 0; i < _size; ++i){
- vector<double> bt;
- j.at("map-building-time").at(i).get_to(bt);
- vector<cell> vc;
- for(int e = 0; e < _size; ++e){
- _map[i][e].set_building_time(bt[e]);
- }
- }
- in.close();
- _possible_loans.clear();
- for(unsigned e = 0; e < j.at("loans"); ++e){
- stringstream ss;
- ss << e;
- loan n(j.at("possible-loan" + ss.str() + "-description"),
- j.at("possible-loan" + ss.str() + "-money"),
- j.at("possible-loan" + ss.str() + "-months"),
- j.at("possible-loan" + ss.str() + "-installment"));
- _possible_loans.push_back(n);
-
- }
- for(unsigned e = 0; e < j.at("asked-loans"); ++e){
- stringstream ss;
- ss << e;
- loan n(j.at("asked-loan" + ss.str() + "-description"),
- j.at("asked-loan" + ss.str() + "-money"),
- j.at("asked-loan" + ss.str() + "-months"),
- j.at("asked-loan" + ss.str() + "-installment"));
- _asked_out_loans.push_back(n);
- }
- j.at("money").get_to(_money);
- j.at("time").get_to(_time);
- j.at("size").get_to(_size);
-
- j.at("population").get_to(_population);
- }
- }
- void city::ecosystem_pollution(vector<vector<cell>>& new_field, int i, int e){
- int base_pollution = _map[i][e].get_building().get_air_pollution();
- int top_limit = i + base_pollution + 1;
- int bottom_limit = i - base_pollution - 1;
- int left_limit = e - base_pollution - 1;
- int right_limit = e + base_pollution + 1;
- int size = _map.size() - 1;
-
- if(bottom_limit < 0)
- bottom_limit = 0;
- if(left_limit < 0)
- left_limit = 0;
- if(right_limit >= size)
- right_limit = size;
- if(top_limit >= size)
- top_limit = size;
- if(base_pollution > 1){
- for(int y = bottom_limit; y <= top_limit; ++y){
- for(int x = left_limit; x <= right_limit; ++x){
- int calculated_pollution = base_pollution - (abs(y - i) + abs(x - e));
- if(calculated_pollution > 0)
- new_field[y][x].set_air_pollution(
- new_field[y][x].get_air_pollution() + calculated_pollution
- );
- }
- }
- }else
- new_field[i][e].set_air_pollution(
- new_field[i][e].get_air_pollution() + base_pollution);
- }
- int city::population(int i, int e){
- if(_map[i][e].get_building().get_type() == RESIDENTIAL and
- _map[i][e].get_electricity() > 0 and _map[i][e].get_access() > 0)
- return _buildings[RESIDENTIAL].get_max_people();
- else
- return 0;
- }
- int city::road(int i, int e){
- int result = 0;
- int size = _map.size() - 1;
- switch(_map[i][e].get_building().get_type()){
- case LAND:{
- result = 0;
- };break;
- case ROAD:{
- result = 4;
- };break;
- case RESIDENTIAL:{
- if(i != size and _map[i+1][e].get_access() != 0)
- result = _map[i+1][e].get_access() - 1;
-
- if(e != size and _map[i][e+1].get_access() > result)
- result = _map[i][e+1].get_access() - 1;
-
- if(i != 0 and _map[i-1][e].get_access() > result)
- result = _map[i-1][e].get_access() - 1;
-
- if(e != 0 and _map[i][e-1].get_access() > result)
- result = _map[i][e-1].get_access() - 1;
-
- };break;
- case POWER_STATION:{
- if(i != size and _map[i+1][e].get_access() != 0)
- result = _map[i+1][e].get_access() - 1;
- if(e != size and _map[i][e+1].get_access() > result)
- result = _map[i][e+1].get_access() - 1;
- if(i != 0 and _map[i-1][e].get_access() > result)
- result = _map[i-1][e].get_access() - 1;
- if(e != 0 and _map[i][e-1].get_access() > result)
- result = _map[i][e-1].get_access() - 1;
- };break;
- case SHOPS:{
- if(i != size and _map[i+1][e].get_access() != 0)
- result = _map[i+1][e].get_access() - 1;
- if(e != size and _map[i][e+1].get_access() > result)
- result = _map[i][e+1].get_access() - 1;
- if(i != 0 and _map[i-1][e].get_access() > result)
- result = _map[i-1][e].get_access() - 1;
- if(e != 0 and _map[i][e-1].get_access() > result)
- result = _map[i][e-1].get_access() - 1;
- };break;
- case INDUSTRY:{
- if(i != size and _map[i+1][e].get_access() != 0)
- result = _map[i+1][e].get_access() - 1;
- if(e != size and _map[i][e+1].get_access() > result)
- result = _map[i][e+1].get_access() - 1;
- if(i != 0 and _map[i-1][e].get_access() > result)
- result = _map[i-1][e].get_access() - 1;
- if(e != 0 and _map[i][e-1].get_access() > result)
- result = _map[i][e-1].get_access() - 1;
- };break;
- case WATER_STATION:{
- if(i != size and _map[i+1][e].get_access() != 0)
- result = _map[i+1][e].get_access() - 1;
- if(e != size and _map[i][e+1].get_access() > result)
- result = _map[i][e+1].get_access() - 1;
- if(i != 0 and _map[i-1][e].get_access() > result)
- result = _map[i-1][e].get_access() - 1;
- if(e != 0 and _map[i][e-1].get_access() > result)
- result = _map[i][e-1].get_access() - 1;
- };break;
- default: result = 0;break;
- }
- return result;
- }
- int city::income(){
- int result = 0;
- int road_costs = 0;
- int electricity_production_costs = 0;
- float loans_debt = 0;
- for(unsigned i = 0; i < _map.size(); ++i){
- for(unsigned e = 0; e < _map[i].size(); ++e){
- if(_map[i][e].get_building().get_type() == RESIDENTIAL and
- _map[i][e].get_electricity() > 0 and _map[i][e].get_access() > 0)
- result += 2;
- else if(_map[i][e].get_building().get_type() == ROAD)
- road_costs += 1;
- else if(_map[i][e].get_building().get_type() == POWER_STATION)
- electricity_production_costs += 5;
- }
- }
- for(unsigned i = 0; i < _asked_out_loans.size(); ++i){
- loans_debt += _asked_out_loans[i].get_installment();
- _asked_out_loans[i].set_months(_asked_out_loans[i].get_months() - 1);
- _asked_out_loans[i].set_money(_asked_out_loans[i].get_money() - _asked_out_loans[i].get_installment());
- if(_asked_out_loans[i].get_months() == 0)
- _asked_out_loans.erase(_asked_out_loans.begin() + i);
- }
- cout << "-------------------" << endl;
- cout << "Monthly review" << endl;
- cout << "Income: " << result << endl;
- cout << "Electricity production costs: " << electricity_production_costs << endl;
- cout << "Road costs: " << road_costs << endl;
- if(_asked_out_loans.size() > 0)
- cout << "Loans installment: " << loans_debt << endl;
- cout << "-------------------" << endl;
- result -= road_costs + electricity_production_costs;
- return result;
- }
- int city::get_needed_residentials(){
- float sum = (2/3.0) * _industry + (1/3.0) * _shops;
- return (int) sum;
- }
- int city::get_needed_industry(){
- float sum = 3 * _industry - _shops;
- sum = sum / 2;
- return (int) sum;
- }
- int city::get_needed_shops(){
- float sum = 3 * _residentials - 2 * _industry;
- return (int) sum;
- }
- void city::get_loan(){
- unsigned e;
- for(unsigned i = 0; i < _possible_loans.size(); ++i){
- cout << "loan " << i <<endl;
- cout << "description " << _possible_loans[i].get_description() << endl;
- cout << "money " << _possible_loans[i].get_money() << endl;
- cout << "months " << _possible_loans[i].get_months() << endl;
- cout << "installment " << _possible_loans[i].get_installment() << endl;
- cout << "--------------------------------------" << endl;
- }
- cout << "loan number" << endl;
- cin >> e;
- if(e < _possible_loans.size()){
- _money += _possible_loans[e].get_money();
- _asked_out_loans.push_back(_possible_loans[e]);
- _possible_loans.erase(_possible_loans.begin() + e);
- }
- }
|