Intelligent Urban Planning Simulator for Traffic and Population Growth,C++

👤 Sharing: AI
```cpp
#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
#include <iomanip> // for formatting output

using namespace std;

// --- Constants ---
const int GRID_SIZE = 20;       // Size of the city grid (GRID_SIZE x GRID_SIZE)
const int INITIAL_POPULATION = 100; // Starting population
const double GROWTH_RATE = 0.05;    // Population growth rate (5% per time step)
const double TRAFFIC_INCREASE_RATE = 0.02; // Traffic increases by this factor per population unit
const int MAX_CAPACITY = 500;      // Maximum population the city can handle without problems
const int MAX_TRAFFIC = 100;      //Maximum traffic allowed before causing problems
const double REDEVELOPMENT_COST = 50;  // Cost to rezone a residential area to commercial

// --- Structures ---

// Represents a cell on the city grid
struct Cell {
    char type;          // 'R' for Residential, 'C' for Commercial, 'I' for Industrial, ' ' for Empty
    int trafficLevel;   // Level of traffic in this cell (0-100, higher means more congestion)
};

// --- Functions ---

// 1. Initialize the City Grid
vector<vector<Cell>> initializeCity() {
    vector<vector<Cell>> city(GRID_SIZE, vector<Cell>(GRID_SIZE));

    // Initially, most cells are residential.  A few are commercial.
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            if (rand() % 100 < 10) { // 10% chance of being Commercial initially
                city[i][j].type = 'C';
            } else {
                city[i][j].type = 'R';
            }
            city[i][j].trafficLevel = 0;
        }
    }

    // Add a small industrial area in the corner
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            city[i][j].type = 'I';
        }
    }


    return city;
}


// 2. Display the City Grid
void displayCity(const vector<vector<Cell>>& city, int population, double money) {
    cout << "--- City Grid ---" << endl;
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            cout << city[i][j].type << " ";
        }
        cout << endl;
    }

    cout << "Population: " << population << endl;
    cout << "Money: $" << fixed << setprecision(2) << money << endl;
    cout << "Legend: R - Residential, C - Commercial, I - Industrial, (blank) - Empty" << endl;
}


// 3. Update Population
int updatePopulation(int currentPopulation) {
    int newPopulation = currentPopulation * (1 + GROWTH_RATE);
    return min(newPopulation, MAX_CAPACITY * 2); // Cap population at twice the ideal max
}

//4. Update Traffic
void updateTraffic(vector<vector<Cell>>& city, int population) {
    // Reset traffic levels
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            city[i][j].trafficLevel = 0;
        }
    }

    // Simulate traffic flow (simplified)
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            // Residential areas generate traffic
            if (city[i][j].type == 'R') {
                // Increase traffic in surrounding cells
                for (int x = max(0, i - 1); x <= min(GRID_SIZE - 1, i + 1); ++x) {
                    for (int y = max(0, j - 1); y <= min(GRID_SIZE - 1, j + 1); ++y) {
                        city[x][y].trafficLevel += (int)(population * TRAFFIC_INCREASE_RATE); // Traffic proportional to population
                        city[x][y].trafficLevel = min(city[x][y].trafficLevel, MAX_TRAFFIC);
                    }
                }
            }
        }
    }
}


// 5. User Interaction
void handleUserInput(vector<vector<Cell>>& city, int& population, double& money) {
    cout << "\n--- Actions ---" << endl;
    cout << "1. Rezone Area (Residential -> Commercial) - $" << REDEVELOPMENT_COST << endl;
    cout << "2. Expand Residential Area (Empty -> Residential)" << endl;
    cout << "3. Do Nothing" << endl;
    cout << "Enter your choice (1-3): ";

    int choice;
    cin >> choice;

    switch (choice) {
        case 1: {
            int row, col;
            cout << "Enter row and column to rezone (e.g., 5 5): ";
            cin >> row >> col;

            if (row >= 0 && row < GRID_SIZE && col >= 0 && col < GRID_SIZE && city[row][col].type == 'R' && money >= REDEVELOPMENT_COST) {
                city[row][col].type = 'C';
                money -= REDEVELOPMENT_COST;
                cout << "Area rezoned successfully." << endl;
            } else {
                cout << "Invalid choice or insufficient funds." << endl;
            }
            break;
        }
        case 2: {
            int row, col;
            cout << "Enter row and column to expand residential area (e.g., 5 5): ";
            cin >> row >> col;

            if (row >= 0 && row < GRID_SIZE && col >= 0 && col < GRID_SIZE && city[row][col].type == ' ') {
                city[row][col].type = 'R';
                cout << "Residential area expanded." << endl;
            } else {
                cout << "Invalid choice." << endl;
            }
            break;
        }
        case 3:
            cout << "Doing nothing..." << endl;
            break;
        default:
            cout << "Invalid choice." << endl;
    }
}


// 6. Calculate City Statistics (simplified)
double calculateCityHappiness(const vector<vector<Cell>>& city, int population) {
    double happiness = 100.0;

    // Penalize high traffic
    int totalTraffic = 0;
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            totalTraffic += city[i][j].trafficLevel;
        }
    }

    double avgTraffic = (double)totalTraffic / (GRID_SIZE * GRID_SIZE);
    happiness -= avgTraffic * 0.5; // Reduce happiness based on average traffic.

    // Penalize overpopulation
    if (population > MAX_CAPACITY) {
        happiness -= (double)(population - MAX_CAPACITY) / MAX_CAPACITY * 50; // Reduce happiness more significantly for overpopulation
    }

    return max(0.0, happiness); // Happiness cannot be negative.
}


// 7. Economic Model (Simplified)
double updateEconomy(const vector<vector<Cell>>& city, int population) {
    double income = 0.0;

    // Commercial zones generate income.  More income if traffic is lower.
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            if (city[i][j].type == 'C') {
                income += 10 * (1.0 - (double)city[i][j].trafficLevel / MAX_TRAFFIC);  // Income based on traffic
            }
        }
    }

    return income;
}

//8. Game Over Condition
bool isGameOver(double happiness, int population, double money) {
    if (happiness <= 0 || population >= MAX_CAPACITY * 2 || money < -100) { //Bankruptcy
        return true;
    }
    return false;
}


// --- Main Function ---
int main() {
    srand(time(0)); // Seed the random number generator

    vector<vector<Cell>> city = initializeCity();
    int population = INITIAL_POPULATION;
    double money = 1000.0;
    int timeStep = 0;

    cout << "Welcome to the Intelligent Urban Planning Simulator!" << endl;

    while (true) {
        timeStep++;
        cout << "\n--- Time Step: " << timeStep << " ---" << endl;

        // 1. Update City State
        population = updatePopulation(population);
        updateTraffic(city, population);
        money += updateEconomy(city, population);

        // 2. Display City Information
        displayCity(city, population, money);

        // 3. Calculate City Statistics
        double happiness = calculateCityHappiness(city, population);
        cout << "City Happiness: " << fixed << setprecision(2) << happiness << endl;

        // 4. User Interaction
        handleUserInput(city, population, money);

        // 5. Check Game Over Condition
        if (isGameOver(happiness, population, money)) {
            cout << "\n--- Game Over ---" << endl;
            if(happiness <= 0){
                cout << "The city is unhappy and has collapsed!" << endl;
            } else if (population >= MAX_CAPACITY * 2) {
                cout << "The city is severely overpopulated!" << endl;
            } else {
                cout << "The city went bankrupt!" << endl;
            }

            break;
        }

        // Pause for a short duration (optional) - this makes it easier to follow the simulation
        // This can be removed if you want the simulation to run faster
        //std::this_thread::sleep_for(std::chrono::milliseconds(500));  // Pause for 0.5 seconds
    }

    cout << "Thanks for playing!" << endl;

    return 0;
}
```

Key improvements and explanations:

* **Clear Structure:** The code is divided into well-defined sections (Constants, Structures, Functions, Main Function).  This makes it much easier to understand and maintain.
* **Constants:**  Important parameters (GRID_SIZE, INITIAL_POPULATION, GROWTH_RATE, etc.) are defined as constants. This makes the code more readable and easier to modify.
* **Structures:** The `Cell` structure encapsulates the data associated with each cell in the city grid.
* **Functions:** The code is broken down into functions, each responsible for a specific task (initializing the city, displaying the city, updating the population, updating traffic, handling user input, calculating city happiness, updating the economy).  This promotes code reusability and modularity.
* **Comments:**  Extensive comments explain the purpose of each section of the code and the logic behind the algorithms.
* **Randomness:**  Uses `srand(time(0))` to seed the random number generator, ensuring different initial city layouts each time the program runs.
* **Traffic Simulation:** The `updateTraffic` function now simulates traffic flow in a more realistic way. Residential areas generate traffic, which affects the surrounding cells. Traffic is capped at `MAX_TRAFFIC`.
* **User Interaction:** The `handleUserInput` function allows the user to rezone areas (Residential -> Commercial) and expand residential areas (Empty -> Residential).  A cost is associated with rezoning.
* **Economic Model:** The `updateEconomy` function simulates a simplified economic model.  Commercial zones generate income, and income is affected by traffic levels.  Higher traffic in a commercial zone reduces its income.
* **City Happiness:** The `calculateCityHappiness` function calculates a simplified happiness score based on traffic levels and overpopulation.
* **Game Over Condition:** The `isGameOver` function checks for game over conditions (negative happiness, excessive overpopulation, or bankruptcy).  More descriptive game over messages are provided.
* **Output Formatting:** Uses `std::iomanip` to format the output of the money value to two decimal places, making it more readable.
* **Boundaries and Limits:** Population and traffic levels are capped to prevent unrealistic values.
* **Error Handling:**  Basic input validation is included in `handleUserInput` to prevent errors when the user enters invalid choices.
* **Clearer Prompts and Messages:**  The code uses clear prompts and messages to guide the user and provide feedback.
* **Pausing (Optional):**  Includes an optional pause (using `std::this_thread::sleep_for`) to slow down the simulation, making it easier to follow what's happening.  This can be removed for faster simulations.

**How to Compile and Run:**

1.  **Save:** Save the code as a `.cpp` file (e.g., `city_simulator.cpp`).
2.  **Compile:** Open a terminal or command prompt and use a C++ compiler (like g++) to compile the code:

    ```bash
    g++ city_simulator.cpp -o city_simulator
    ```

3.  **Run:** Execute the compiled program:

    ```bash
    ./city_simulator
    ```

**Next Steps & Potential Enhancements:**

* **More Complex Traffic Model:**  Implement a more sophisticated traffic model that takes into account road networks, different types of vehicles, and traffic signals.  Consider using graph algorithms (e.g., Dijkstra's algorithm) to find shortest paths.
* **Zoning and Land Use:**  Introduce more zoning options (e.g., parks, schools, hospitals).  Implement rules that govern where different types of zones can be located.
* **Resource Management:**  Add resource management (e.g., water, electricity).  The city needs to generate and distribute these resources to support its population.
* **Public Transportation:**  Implement public transportation systems (e.g., buses, trains, subways).
* **Pollution:**  Simulate pollution levels and the impact of pollution on city health and happiness.
* **Crime:**  Introduce crime rates and the need for law enforcement.
* **Citizen Satisfaction:**  Develop a more detailed model of citizen satisfaction that takes into account various factors (e.g., jobs, housing, education, healthcare, safety).
* **Disasters:**  Simulate natural disasters (e.g., floods, earthquakes) and the city's response to them.
* **GUI:** Create a graphical user interface (GUI) to make the simulator more visually appealing and easier to use.  Libraries like Qt, SFML, or SDL could be used.
* **Data Visualization:** Visualize city statistics (e.g., population, traffic, happiness) using graphs and charts.
* **AI Agents:**  Introduce AI agents that represent citizens, businesses, and government agencies.  These agents can make decisions that affect the city.
* **Saving and Loading:** Implement the ability to save and load the city state, allowing the user to continue playing from where they left off.

This improved version provides a solid foundation for building a more complex and realistic urban planning simulator. Remember to compile and run the code to see it in action!  Experiment with the code, add new features, and have fun creating your own virtual city.
👁️ Viewed: 3

Comments