Per-Frame Bounce Controller for a Flappy Bird-Style Pipe Game Simulator
Company: StubHub
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Online Assessment
In an online assessment you receive a small Python project for a Flappy Bird-style game (the task is called BouncyCosmo) and must implement the strategy function `should_bounce(params)`. The simulator calls it once per frame, and the function returns whether the character should bounce (jump) in that frame. The goal is to steer the character through every pipe on the map without a collision. The parameters include the character's position and velocity, the gravity, and the complete map of the level. The project comes with the simulator, a visual viewer and tests, and you may read the simulator's source code to learn the exact physics rules.
One detail of the simulator's frame update matters a great deal: in each frame it first adds gravity to the velocity, then updates the position and checks for collisions, and only after that sets the bounce velocity if a bounce was requested. A bounce therefore changes the motion only from the next frame on.
### Clarifying Questions
- Is the whole map fixed and known from the first frame, so that a plan can be computed once, or can it change during a run?
- Are positions and velocities integers or floating-point numbers, and does the character move forward by a constant amount each frame?
- What exactly counts as a collision: the size of the character's hitbox, whether touching a pipe's edge counts, and whether leaving the top or bottom of the screen ends the run?
- What time limit applies, per test or for the whole suite?
### Part 1 — Reproduce the physics exactly
Read the simulator and write a function that takes the character's state and a bounce decision for one frame and returns the next state, or reports a collision, exactly as the simulator would.
```hint Line up the frame
Write out the operations of one frame in the simulator's order, then ask in which frame a bounce requested now first changes the character's height.
```
#### What This Part Should Cover
- The order of operations within a frame and the one-frame delay of a bounce
- Collision boundaries: hitbox, pipe edges, the limits of each gap and the screen bounds
- A test that compares your model with the real simulator frame by frame
### Part 2 — Pass every pipe
Implement `should_bounce(params)` so that the character passes every pipe on each test map, including maps with narrow gaps.
```hint Why reacting is not enough
Think about why a rule that looks only at the current height and the next pipe can fail in a narrow gap when every bounce acts one frame late.
```
#### What This Part Should Cover
- A planning method that explores bounce decisions over future frames instead of reacting to the current frame only
- How repeated and doomed states are discarded
- How `should_bounce` turns the plan into one decision per frame, and what it does if the observed state differs from the plan
### Part 3 — Stay within the time limit
Narrow pipes make the search large, and the tests have a time limit. Explain how you keep the total run time within it without losing maps that only a precise path can pass.
```hint Count the real situations
Ask how many genuinely different situations the character can be in at a given frame, and what you would do if a faster shortcut finds no path.
```
#### What This Part Should Cover
- What drives the search's cost, and how deduplicating states bounds it
- A fast first attempt with a complete fallback
- Planning once per map and reusing the plan instead of searching every frame
### What a Strong Answer Covers
- Reads simulator.py before writing the strategy and reproduces its rules exactly
- Applies the one-frame bounce delay consistently in every prediction
- Uses a search over states with deduplication rather than a height threshold alone
- Treats collision boundaries and screen limits precisely
- Keeps the run time within the limit, and checks every map with the provided tests and viewer
### Follow-up Questions
- Positions are floating-point numbers. How do you deduplicate states without merging states that behave differently near a pipe edge?
- How would you show that a map has no solution at all, rather than only failing to find one?
- If the map were revealed only a few pipes ahead, how would the strategy change?
- Several bounce sequences pass a map. How would you choose the one with the most safety margin?
Overview: Implement should_bounce for a Flappy Bird-style game in a provided Python project, deciding each frame whether the character should bounce so that it passes every pipe. It tests reading a simulator to model its physics exactly, including a one-frame bounce delay, along with state-space search, collision boundaries and run-time limits.
Read the full StubHub Software Engineer interview experience this question came from