Examples
Input: {'bird_y': 18, 'bird_v': 2, 'bird_x': 5, 'screen_height': 20, 'next_pipe': {'x': 15, 'width': 3, 'gap_top': 6, 'gap_bottom': 12}}
Expected Output: True
Explanation: If the bird does not jump, it hits the ground on the first simulated frame. Jumping survives longer, so the policy returns True.
Input: {'bird_y': 4, 'bird_v': -2, 'bird_x': 5, 'screen_height': 20, 'next_pipe': {'x': 7, 'width': 2, 'gap_top': 0, 'gap_bottom': 10}}
Expected Output: False
Explanation: The bird is already high and moving upward. Jumping would immediately go out of bounds above the screen, while waiting safely passes the pipe.
Input: {'bird_y': 15, 'bird_v': 0, 'bird_x': 5, 'screen_height': 20, 'next_pipe': {'x': 6, 'width': 1, 'gap_top': 5, 'gap_bottom': 10}}
Expected Output: True
Explanation: The pipe overlaps on the next frame. Without jumping, the bird is below the gap and collides immediately. Jumping moves it into the gap and past the width-1 pipe.
Input: {'bird_y': 17, 'bird_v': 0, 'bird_x': 5, 'screen_height': 20, 'next_pipe': {'x': 6, 'width': 1, 'gap_top': 5, 'gap_bottom': 18}}
Expected Output: True
Explanation: Both actions survive for the same number of frames, so the tie is broken by distance to the gap center. Jumping places the bird closer to the center of the gap.
Input: {'bird_y': 15, 'bird_v': -1, 'bird_x': 5, 'screen_height': 20, 'next_pipe': {'x': 6, 'width': 1, 'gap_top': 5, 'gap_bottom': 14}}
Expected Output: True
Explanation: Without jumping, the bird reaches `y = 14`, which is exactly `gap_bottom` and therefore a collision because the gap is strict. Jumping avoids that boundary collision.
Input: {'bird_y': 17, 'bird_v': 0, 'bird_x': 5, 'screen_height': 25, 'next_pipe': {'x': 6, 'width': 1, 'gap_top': 4, 'gap_bottom': 22}}
Expected Output: False
Explanation: Both actions survive equally long and are equally close to the gap center during overlap, so the deterministic final tie-break returns False.