Implement 2048 Board Tilts in Four Directions with Merging and Game-Over Detection

Quick Overview

Implement the move logic of the 2048 sliding-tile game on a 4x4 board: slide and merge tiles for left, right, up and down swipes so each tile merges at most once, then decide when no swipe can change the board. Tests edge-case precision, code reuse across directions and a correct game-over rule.

Implement 2048 Board Tilts in Four Directions with Merging and Game-Over Detection

Company: Glean

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

You are implementing the move logic of the sliding-tile game 2048. The board is a 4 x 4 grid. Each cell is either empty, written `0`, or holds a tile whose value is a power of two (`2`, `4`, `8`, ...). A swipe (the "tilt") in one of four directions (up, down, left or right) slides every tile as far as it can go in that direction and collapses the board: when two tiles with the same value meet, they merge into one tile holding their sum. This is the game itself, not a puzzle about the number 2048, and it has several edge cases. Build it in the order of the parts below. The interviewer's follow-up was how to tell that the game is over. ### Constraints and Clarifications - The board is 4 x 4, given as a list of rows with row `0` at the top. - Spawning a new random tile after each move belongs to the game loop, not to the tilt itself. Keep the tilt deterministic so it can be unit tested. - You may return a new board or update the board in place, but say which. ### Clarifying Questions - When three or four equal tiles sit in one line, which pair merges first? - Can a tile that was just created by a merge merge again during the same swipe? - Should the tilt report whether it changed anything, so the caller knows whether to spawn a tile? - Does reaching the 2048 tile end the game, or does play continue? ### Part 1 — Tilt in one direction Implement the left swipe for the whole board. Walk the rows `[2, 2, 2, 0]`, `[2, 2, 2, 2]`, `[4, 4, 8, 0]` and `[2, 0, 0, 2]` through your code and state its complexity. ```hint One line is enough A left swipe never moves a tile out of its row. Solve one row as a plain list first, then decide what your merge pass must remember so that a tile never takes part in two merges. ``` #### What This Part Should Cover - Sliding across gaps as well as merging adjacent equal tiles - The merge-once rule and the merge order for three or four equal tiles - Producing a row of the same length, padded with empty cells ### Part 2 — All four directions Extend the solution to right, up and down swipes. Aim for a design in which the other three directions reuse the first instead of copying it. ```hint Reuse the line solver A right swipe on a row behaves like a left swipe on the same row read backwards. Ask which sequence of cells a column swipe reads, and in which order. ``` #### What This Part Should Cover - One line-merging routine shared by all four directions - Correct merge priority for right and down swipes - Detecting whether a swipe changed the board at all ### Part 3 — Game over Follow-up: how do you decide that the game is over? Implement the check and say when the game loop should call it. ```hint What a dead board looks like The game ends when no swipe in any direction would change the board. Work out which local conditions let some swipe change it. ``` #### What This Part Should Cover - The exact game-over condition, not just "the board is full" - An efficient check that does not need to simulate every swipe, or a justified choice to simulate - Where the check belongs relative to spawning the next tile ### What a Strong Answer Covers - Merge semantics stated before coding and checked against the tricky rows - Code that handles all four directions without four copies of the logic - A game-over rule that accounts for a full board that still has a legal merge - Small, explicit test cases for the edge cases - Correct complexity for a tilt and for the game-over check ### Follow-up Questions - How would you add tile spawning while keeping the game testable, for example with an injectable random source? - How would you track the score, which in the real game grows by the value of every merged tile? - What changes if the board is `n x n` instead of 4 x 4? - How would you support undoing the last move?

Overview: Implement the move logic of the 2048 sliding-tile game on a 4x4 board: slide and merge tiles for left, right, up and down swipes so each tile merges at most once, then decide when no swipe can change the board. Tests edge-case precision, code reuse across directions and a correct game-over rule.

|Home/Software Engineering Fundamentals/Glean
Glean logo
Glean
Sep 30, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

You are implementing the move logic of the sliding-tile game 2048. The board is a 4 x 4 grid. Each cell is either empty, written 0, or holds a tile whose value is a power of two (2, 4, 8, ...). A swipe (the "tilt") in one of four directions (up, down, left or right) slides every tile as far as it can go in that direction and collapses the board: when two tiles with the same value meet, they merge into one tile holding their sum.

This is the game itself, not a puzzle about the number 2048, and it has several edge cases. Build it in the order of the parts below. The interviewer's follow-up was how to tell that the game is over.

Constraints and Clarifications

  • The board is 4 x 4, given as a list of rows with row 0 at the top.
  • Spawning a new random tile after each move belongs to the game loop, not to the tilt itself. Keep the tilt deterministic so it can be unit tested.
  • You may return a new board or update the board in place, but say which.

Clarifying Questions Guidance

  • When three or four equal tiles sit in one line, which pair merges first?
  • Can a tile that was just created by a merge merge again during the same swipe?
  • Should the tilt report whether it changed anything, so the caller knows whether to spawn a tile?
  • Does reaching the 2048 tile end the game, or does play continue?

Part 1 — Tilt in one direction

Implement the left swipe for the whole board. Walk the rows [2, 2, 2, 0], [2, 2, 2, 2], [4, 4, 8, 0] and [2, 0, 0, 2] through your code and state its complexity.

What This Part Should Cover Guidance

  • Sliding across gaps as well as merging adjacent equal tiles
  • The merge-once rule and the merge order for three or four equal tiles
  • Producing a row of the same length, padded with empty cells

Part 2 — All four directions

Extend the solution to right, up and down swipes. Aim for a design in which the other three directions reuse the first instead of copying it.

What This Part Should Cover Guidance

  • One line-merging routine shared by all four directions
  • Correct merge priority for right and down swipes
  • Detecting whether a swipe changed the board at all

Part 3 — Game over

Follow-up: how do you decide that the game is over? Implement the check and say when the game loop should call it.

What This Part Should Cover Guidance

  • The exact game-over condition, not just "the board is full"
  • An efficient check that does not need to simulate every swipe, or a justified choice to simulate
  • Where the check belongs relative to spawning the next tile

What a Strong Answer Covers Guidance

  • Merge semantics stated before coding and checked against the tricky rows
  • Code that handles all four directions without four copies of the logic
  • A game-over rule that accounts for a full board that still has a legal merge
  • Small, explicit test cases for the edge cases
  • Correct complexity for a tilt and for the game-over check

Follow-up Questions Guidance

  • How would you add tile spawning while keeping the game testable, for example with an injectable random source?
  • How would you track the score, which in the real game grows by the value of every merged tile?
  • What changes if the board is n x n instead of 4 x 4?
  • How would you support undoing the last move?
Loading comments...