How do I create a random path?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
"Random path" can mean several different things, so the first step is deciding what constraints the path must satisfy. A path for a game enemy, a simulation, and a maze generator are all random in different ways, and the code should reflect that instead of choosing random steps blindly.
Start with the Rules of Movement
Before writing code, define:
- the space, such as a 2D grid
- the starting point
- the number of steps or target point
- whether revisiting positions is allowed
- whether the path must stay inside bounds
The simplest version is a bounded random walk. At each step, choose one of the allowed directions and move there.
This produces a valid random path, but it may revisit the same cell many times. That is fine for diffusion-like simulations and wandering agents, but not for every use case.
Create a Non-Repeating Random Path
If you want a path that does not cross itself, track visited cells and only choose from unvisited neighbors.
This version stops early if it runs out of valid unvisited moves. That is not a bug. It is a consequence of the constraints.
Random Path from Start to Goal
Sometimes a path must be random but still reach a destination. In that case, a pure random walk is the wrong tool because it may never arrive. A better pattern is randomized depth-first search or randomized breadth-first search.
Here is a simple randomized depth-first search on a grid:
Because the neighbor order is shuffled, the path is different on different runs, but it still obeys the start-to-goal requirement.
Add Obstacles or Bias
Real path generation often needs more than uniform randomness. You may want to avoid walls, prefer forward movement, or create smoother turns.
One simple improvement is weighted choice. For example, if moving east should be twice as likely as other directions, assign weights and sample from them. In Python, random.choices handles that cleanly.
You can also filter out blocked cells:
Then skip those coordinates when building the candidate move list.
The general rule is simple: randomness decides among valid options, but your constraints define what "valid" means.
Common Pitfalls
The biggest mistake is not defining the problem precisely. "Create a random path" is underspecified until you decide whether the path can revisit nodes, whether it must terminate at a goal, and what counts as a legal move.
Another common issue is generating moves first and checking validity later. That often creates messy code with lots of rejected steps. Build the valid candidate list first, then choose from it.
People also forget that stronger constraints reduce randomness. A path that must avoid revisits, avoid obstacles, stay in bounds, and hit a specific target cannot be generated with a trivial random walk.
Finally, be careful with reproducibility. If you need testable behavior, set a seed with random.seed(...) before generating the path.
Summary
- Define movement rules before writing the generator.
- Use a random walk for simple wandering behavior.
- Track visited cells when the path must not cross itself.
- Use randomized search when the path must reach a goal.
- Randomness should operate within constraints, not replace them.

