Katkat

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

GleanSoftware Engineer · Onsite

Last updated

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.

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.

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.

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.

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

Hints

Hint 1

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.

Hint 2

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.

Hint 3

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.

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?