ASCII Terrain Renderer
Build a C++ program that creates random landscapes and draws them in the terminal as colored text: deep water, shallow water, sand, grass, forest, rock and snow, depending on the height of each point. The heights come from a noise function (value noise or Perlin noise, layered at several scales), which produces natural-looking hills and valleys instead of random static, and a light direction adds shading so slopes look three-dimensional. The same seed always produces the same map. It's a fun first C++ project: you'll learn 2D arrays with std::vector, random numbers with seeds, interpolation, a bit of math for shading, ANSI colors in the terminal, and command-line options.
- Estimate
- ~8.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
CMake · C++ STL
Project roadmap
- 01
Define the output
~1hWrite README.md: the command (terrain --width 80 --height 40 --seed 42 --scale 20), the height bands and their characters and colors (for example ~ blue for deep water, . yellow for sand, " green for grass, ^ grey for rock and * white for snow), and an example output. Set up a CMake project. Done when: README.md shows the options and an example.
- 02
Store the height map
~1hWrite a HeightMap class with a width, a height and heights as floats between 0 and 1 in a std::vector, with at(x, y) that checks bounds. Parse and validate the command-line options (sizes between 10 and 300, a positive scale). Fill the map with plain random values from std::mt19937 seeded with the seed, just to test it. Done when: the map is created with the requested size and seed.
- 03
Generate smooth terrain with noise
~2hImplement value noise: random values on a coarse grid, smoothly interpolated between grid points (with a smoothstep curve). Add several layers (octaves), each with double the detail and half the strength, and normalize the result to 0 to 1. Done when: the same seed always gives the same map, and the map shows smooth hills instead of static.
- 04
Render with colors and shading
~2hMap each height to a band's character and color using ANSI escape codes, with --no-color for plain output. Add shading: compare each point's height with its neighbor towards the light, and make slopes facing the light brighter and those facing away darker. Done when: the terminal shows a colorful, shaded landscape.
- 05
Add options and export
~1hAdd --sea-level to shift the water line and --out map.txt to save the map (without colors), and print the share of each terrain type below the map. Handle a terminal narrower than the map with a warning. Done when: changing the sea level visibly floods or drains the map, and the saved file matches the screen.
- 06
Test it
~1.5hWrite tests (with doctest or Catch2): the same seed gives the same map, different seeds give different maps, heights always stay between 0 and 1, the band mapping for boundary values, and option validation. Done when: all tests pass.
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack