Welcome to ProjectPy.com! In this tutorial, we will embark on an exciting journey to build a city growth simulator in Python. This project will not only hone your programming skills but also provide a practical understanding of simulation concepts, object-oriented programming, and algorithm design. By the end of this tutorial, you will have a fully functional city growth simulator that visualizes a settlement evolving into a metropolis over 200 simulated years.
Introduction
The idea of simulating urban growth has fascinated developers and urban planners alike. A city growth simulator can serve multiple purposes: it can help visualize urban planning, study population dynamics, or even provide engaging content for games. In our project, we will create a time-lapse video showcasing a small riverside settlement evolving into a sprawling megacity. The simulator will incorporate various growth mechanics, including road extension, zoning, and environmental features, making it a rich learning experience.
City Grid Configuration
This snippet sets up the configuration for the city simulation, defining parameters such as frame rate, duration, and grid dimensions, which are crucial for controlling the simulation’s visual output.
π Recommended Python Learning Resources
Level up your Python skills with these hand-picked resources:
Data Structures Flashcards with Python Examples β 338 Cards | PDF, Anki Deck & HTML Study App | Coding Interview Prep
Data Structures Flashcards with Python Examples β 338 Cards | PDF, Anki Deck & HTML Study App | Coding Interview Prep
AP Chemistry Flashcards | 700 Study Cards – Flashcards PDF – Offline Interactive HTML App – Anki Deck – Digital Download
AP Chemistry Flashcards | 700 Study Cards – Flashcards PDF – Offline Interactive HTML App – Anki Deck – Digital Download
AP Biology Flashcards | 800 Study Cards, PDF – Anki Deck – Interactive HTML App – Digital Download
AP Biology Flashcards | 800 Study Cards, PDF – Anki Deck – Interactive HTML App – Digital Download
Anatomy and Physiology Flashcards | 800 Study Cards, Interactive HTML App – Anki Deck & Digital Download
Anatomy and Physiology Flashcards | 800 Study Cards, Interactive HTML App – Anki Deck & Digital Download
Cashier’s Deposit Slip Printable PDF | Sticker for 4.5Γ10.375 Deposit Envelope | 5 Colors | US Letter, A4 & Exact Size | Instant Download
Cashier’s Deposit Slip Printable PDF | Sticker for 4.5Γ10.375 Deposit Envelope | 5 Colors | US Letter, A4 & Exact Size | Instant Download
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# CONFIG
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
FPS = 30
DURATION_SEC = 70
TOTAL_FRAMES = FPS * DURATION_SEC
SIM_W, SIM_H = 1920, 1920
# Simulation grid
GRID_W, GRID_H = 320, 320 # city grid cells
CELL_W = SIM_W // GRID_W # 6 px per cell
CELL_H = SIM_H // GRID_H
# City centre
CX, CY = GRID_W // 2, GRID_H // 2 # 160, 160
Prerequisites and Setup
Before we dive into the implementation, make sure you have the following prerequisites:
Terrain Generation
This function generates a terrain grid for the city simulation, creating a river using a sine wave pattern, which demonstrates how to manipulate arrays and create visual features in a grid-based environment.
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# TERRAIN (river, hills β static)
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def build_terrain():
"""Returns terrain grid: WATER or GRASS cells."""
grid = np.full((GRID_H, GRID_W), EMPTY, dtype=np.int32)
# River: curves diagonally across the map
rng = np.random.default_rng(42)
river_x = CX - 30
for y in range(GRID_H):
# Sinuous river
x_off = int(12 * math.sin(y * 0.04) + 6 * math.sin(y * 0.09))
for dx in range(-4, 5):
rx = river_x + x_off + dx
if 0 <= rx < GRID_W:
grid[y, rx] = WATER
return grid
- Python 3.x: This tutorial assumes you have a working knowledge of Python. If you need to install Python, visit the official Python website.
- Libraries: You will need to install the OpenCV and NumPy libraries. You can do this using pip:
pip install opencv-python numpy
Once you have your environment set up, you can download the project files, particularly City Growth Time-Lapse__city_growth_video.py, which contains the complete implementation of our simulator.
Core Concepts Explanation
To build our city growth simulator, we will explore several core concepts:
City State Initialization
This class initializes the city state by setting up the grid, density, and other properties, showcasing object-oriented programming principles and how to manage complex state in a simulation.
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# CITY SIMULATION STATE
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
class CityState:
def __init__(self, terrain):
self.grid = terrain.copy()
self.density = np.zeros((GRID_H, GRID_W), dtype=np.float32)
self.age = np.zeros((GRID_H, GRID_W), dtype=np.float32)
self.road_dist = np.full((GRID_H, GRID_W), 9999.0)
self.population = 0
self.year = YEAR_START
self._init_settlement()
def _init_settlement(self):
"""Place the original village at the river crossing."""
# River bridge / ford point
bridge_y = CY
bridge_x = CX - 30 + int(12 * math.sin(bridge_y * 0.04))
...
1. Simulation Configuration
The simulation’s configuration is crucial for controlling the visual output and performance. We define parameters such as frame rate, simulation duration, and grid dimensions. This setup allows us to tailor the simulation to our desired outcome, ensuring a smooth visual experience.
2. Terrain Generation
Creating a visually appealing and functional terrain is fundamental to our simulation. We will generate a terrain grid using a sine wave pattern to simulate a river and hills. This not only makes the city more realistic but also impacts how the city grows around these features.
3. City State Management
To manage the complexity of the simulation, we will encapsulate the city state in a class. This object-oriented approach allows us to keep track of various properties such as grid configuration, population density, and the status of different city zones.
4. Pathfinding Algorithms
As the city grows, we need to calculate distances from roads to various city cells. Implementing a breadth-first search (BFS) algorithm will help us identify the shortest paths for road connections and urban development. Understanding BFS will also enhance your algorithmic thinking.
Step-by-Step Implementation Walkthrough
Now that we have a solid understanding of the core concepts, letβs walk through the implementation of our city growth simulator step-by-step.
Road Distance Calculation
This method uses breadth-first search (BFS) to calculate the distance from each cell to the nearest road, illustrating an important algorithmic technique for pathfinding in grid-based simulations.
def _update_road_dist(self):
"""BFS distance from any road cell."""
from collections import deque
q = deque()
visited = np.full((GRID_H, GRID_W), False)
for gy in range(GRID_H):
for gx in range(GRID_W):
if self.grid[gy, gx] in (ROAD, RAIL):
self.road_dist[gy, gx] = 0
q.append((gx, gy, 0))
visited[gy, gx] = True
while q:
x, y, d = q.popleft()
for dy, dx in [(-1,0),(1,0),(0,-1),(0,1)]:
nx, ny = x+dx, y+dy
if (0<=nx<GRID_W and 0<=ny<GRID_H and
not visited[ny,nx] and
self.grid[ny,nx] != WATER):
visited[ny,nx] = True
self.road_dist[ny,nx] = d+1
q.append((nx,ny,d+1))
Step 1: Setting Up the Configuration
We begin by defining our simulation parameters, including the frames per second (FPS), duration, and grid dimensions. This initial setup lays the groundwork for our entire simulation.
Step 2: Building the Terrain
Next, we implement the terrain generation function. This function will create a static grid that represents our cityβs landscape, including rivers and hills. This step is crucial as it will shape how our city expands over time.
Step 3: Initializing the City State
We will create a class to manage the city state. This class will hold the grid, population, and zoning information. By encapsulating this data, we can easily modify and access city properties throughout the simulation.
Step 4: Implementing Growth Mechanics
After initializing the city state, we will implement the growth mechanics. This includes functions that handle road extension, zoning changes from residential to commercial, and the formation of parks. Each of these mechanics will be triggered based on specific conditions, allowing us to simulate realistic urban development.
Step 5: Visualizing the Growth
Once the growth mechanics are in place, we need to visualize the cityβs transformation over the specified duration. We will use OpenCV to render frames of the city as it evolves, ultimately compiling these frames into a time-lapse video.
Step 6: Adding Advanced Features
As an optional enhancement, we can introduce advanced features such as night mode, where city lights illuminate the skyline, or a real-time population counter that displays the cityβs growth dynamics. These features not only enrich the simulation but also provide valuable insights into urban development.
Advanced Features or Optimizations
After completing the basic implementation, consider exploring more advanced features and optimizations:
City Growth Step
This method simulates the growth of the city by determining the number of growth actions based on the current year and phase, demonstrating how to manage dynamic changes in the simulation over time.
def step(self, year: float, phase: str, rng):
"""Advance city growth one simulation tick."""
self.year = year
t = (year - YEAR_START) / YEAR_RANGE # 0..1
# How many growth actions per tick (ramp up over time)
n_actions = int(4 + t * 40)
for _ in range(n_actions):
action = rng.random()
if phase == "village":
self._grow_road(rng, max_len=8, bias_angle=None)
self._fill_block(rng, RESIDENTIAL, max_dist=12, density_val=0.4)
...
- Dynamic Weather Systems: Implement weather changes that can affect city growth, such as floods or droughts.
- Advanced Pathfinding: Explore Dijkstra’s algorithm or A* for more efficient pathfinding in complex city layouts.
- Data Visualization: Integrate libraries like Matplotlib to visualize city growth statistics over time.
Practical Applications
The city growth simulator can be applied in various domains, including:
- Urban Planning: City planners can utilize the simulator to visualize potential growth scenarios and make informed decisions about infrastructure development.
- Game Development: The principles learned can be applied to create engaging city-building games.
- Data Science: Students of data science can analyze population dynamics and urbanization trends through simulation data.
Common Pitfalls and Solutions
As you work on the simulator, you may encounter some common pitfalls:
- Performance Issues: If the simulation runs slowly, consider optimizing your algorithms or reducing the grid size.
- Visual Artifacts: Ensure that the rendering logic is correctly implemented to avoid glitches in the visual output.
- Complexity Management: As the codebase grows, maintain organization by using modular functions and classes.
Conclusion and Next Steps
Congratulations! You have successfully built a city growth simulator in Python. This project has allowed you to explore important programming concepts such as simulation design, object-oriented programming, and algorithm implementation.
As a next step, consider enhancing your simulator with the advanced features discussed or exploring different simulation scenarios. The skills and concepts you’ve learned here can be applied to a wide range of projects, from game development to real-world urban planning simulations.
Thank you for joining us on this journey! We hope you enjoyed building your city growth simulator and look forward to seeing your unique implementations!
About This Tutorial: This code tutorial is designed to help you learn Python programming through practical examples. Always test code in a development environment first and adapt it to your specific needs.
Want to accelerate your Python learning? Check out our premium Python resources including Flashcards, Cheat Sheets, Interivew preparation guides, Certification guides, and a range of tutorials on various technical areas.


