PracHub
QuestionsCoachesLearningGuidesInterview Prep
|Home/Software Engineering Fundamentals/Asana

Design a 2048 Game

Last updated: Jun 22, 2026

Quick Overview

This question evaluates object-oriented design, state management, deterministic randomness handling, and algorithmic reasoning for implementing game rules on a configurable N x N grid.

  • medium
  • Asana
  • Software Engineering Fundamentals
  • Software Engineer

Design a 2048 Game

Company: Asana

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

Design the object model and core game logic for a **2048 game** on an `N x N` grid. This is an object-oriented design problem: focus on the classes, their responsibilities, the relationships between them, and the algorithm for a move — not on the UI or rendering. For reference, 2048 is a sliding-tile puzzle. The player moves all tiles in one of four directions; tiles slide as far as they can, and two adjacent tiles of equal value merge into one tile of their sum. After every move that changes the board, a new tile spawns in a random empty cell. ### Constraints & Assumptions - The grid is square, `N x N`, with `N = 4` by default but configurable. - Tile values are powers of two; empty cells are represented by `0`. - A new tile is a `2` with probability $0.9$ and a `4` with probability $0.1$ (configurable). - The game starts with two random tiles already placed. - The default win condition is reaching a `2048` tile; the game may continue after winning. - The game logic must be deterministically testable — randomness has to be injectable so tests are reproducible. - Assume a single local player; no networking or persistence is required (but the design should not preclude them). ### The Problem Produce a class model and the core logic that satisfies the following requirements: - **Initialization** — start a board with two random tiles. - **Moves** — support `UP`, `DOWN`, `LEFT`, and `RIGHT`. - **Slide & merge** — implement the standard rules: tiles slide toward the move direction, and each tile may merge **at most once per move**. - **Scoring** — increase the score by the value of each merged tile. - **Tile spawn** — spawn a new tile **only** when a move actually changes the board. - **State detection** — detect the win state and the game-over state. - **Separation of concerns** — keep UI/presentation strictly out of the game logic. Also discuss how you would support these extensions without rewriting the merge logic: **undo**, custom board sizes, deterministic tests, and configurable spawn probabilities. ```hint Look for the repeated operation Before writing four separate move handlers, ask whether `UP`/`DOWN`/`RIGHT` are genuinely different from `LEFT`, or whether they're the same operation viewed from a different angle. If you can reduce them to one case, what's the smallest unit of the board that operation acts on? ``` ```hint The merge rule has a trap The "each tile merges at most once per move" rule is the easiest thing to get wrong. Pick a concrete line that exposes the ambiguity and decide its result *before* coding: what should `2 2 2` become when slid? Your answer here dictates exactly how your merge loop must advance. ``` ```hint Which pieces deserve to be pulled out? Two parts of this system are the ones you'll most want to test in isolation and vary later: the rule that's easy to get wrong, and the part that's non-deterministic. Consider what the `Game` should depend on so that neither of those is hardwired into it. ``` ```hint Game over isn't "board full" Watch out: a completely full board can still have a legal move. Think about what actually has to be true for *every* direction to be blocked at once — that condition, not "no empty cells," is your game-over test. ``` ### Clarifying Questions to Ask - Is the board always square, and is `N` fixed at 4 or configurable? - After reaching `2048`, does the game end immediately or can the player keep playing for a higher tile? - What are the exact spawn probabilities for `2` vs `4`, and must they be configurable? - Is undo a hard requirement, and if so, how many steps deep? - Do we need persistence (save/resume) or networking, or is this a single local session? - Should the score include only merge gains, or are there bonus/penalty rules? ### What a Strong Answer Covers - A clean class breakdown with single-responsibility classes and clear ownership of state vs. rules vs. randomness vs. presentation. - The "one line-merge function + grid transforms" insight that unifies the four directions. - Correct handling of the at-most-one-merge-per-move rule and the move-must-change-board-before-spawn rule. - Correct, non-trivial win **and** game-over detection (game-over ≠ board full). - Dependency injection of the random source for deterministic testing. - A concrete testing strategy (exhaustive line-merge cases, all four directions, seeded randomness, win/lose/undo integration). - How the chosen abstractions make the extensions (undo, board size, spawn config) cheap, and the time/space complexity of a move ($O(N^2)$). ### Follow-up Questions - How would you implement **undo** with minimal memory? Compare snapshotting the whole board vs. recording a reversible move delta, including how merges and the spawned tile complicate a pure inverse. - How would you detect game-over *efficiently* if `N` were large — can you maintain it incrementally instead of scanning the whole board after every move? - How would you adapt this design to a multiplayer or server-authoritative version where the server must validate moves and prevent cheating? - How would you generalize from "merge equal values into their sum" to a configurable rule (e.g., a different target tile, or Fibonacci-style merges) without touching the slide logic?

Quick Answer: This question evaluates object-oriented design, state management, deterministic randomness handling, and algorithmic reasoning for implementing game rules on a configurable N x N grid.

Related Interview Questions

  • Design an Extensible Animal-Chess Game Engine - Asana (medium)
  • Model and Solve a Rectangular Jigsaw Puzzle - Asana (medium)
  • Design a Testable 2048 Game Engine - Asana (medium)
  • Design and Solve a Rotatable Jigsaw Puzzle - Asana (medium)
|Home/Software Engineering Fundamentals/Asana

Design a 2048 Game

Asana logo
Asana
Apr 2, 2026, 12:00 AM
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
54
0

Design the object model and core game logic for a 2048 game on an N x N grid. This is an object-oriented design problem: focus on the classes, their responsibilities, the relationships between them, and the algorithm for a move — not on the UI or rendering.

For reference, 2048 is a sliding-tile puzzle. The player moves all tiles in one of four directions; tiles slide as far as they can, and two adjacent tiles of equal value merge into one tile of their sum. After every move that changes the board, a new tile spawns in a random empty cell.

Constraints & Assumptions

  • The grid is square, N x N , with N = 4 by default but configurable.
  • Tile values are powers of two; empty cells are represented by 0 .
  • A new tile is a 2 with probability 0.90.90.9 and a 4 with probability 0.10.10.1 (configurable).
  • The game starts with two random tiles already placed.
  • The default win condition is reaching a 2048 tile; the game may continue after winning.
  • The game logic must be deterministically testable — randomness has to be injectable so tests are reproducible.
  • Assume a single local player; no networking or persistence is required (but the design should not preclude them).

The Problem

Produce a class model and the core logic that satisfies the following requirements:

  • Initialization — start a board with two random tiles.
  • Moves — support UP , DOWN , LEFT , and RIGHT .
  • Slide & merge — implement the standard rules: tiles slide toward the move direction, and each tile may merge at most once per move .
  • Scoring — increase the score by the value of each merged tile.
  • Tile spawn — spawn a new tile only when a move actually changes the board.
  • State detection — detect the win state and the game-over state.
  • Separation of concerns — keep UI/presentation strictly out of the game logic.

Also discuss how you would support these extensions without rewriting the merge logic: undo, custom board sizes, deterministic tests, and configurable spawn probabilities.

Clarifying Questions to Ask

  • Is the board always square, and is N fixed at 4 or configurable?
  • After reaching 2048 , does the game end immediately or can the player keep playing for a higher tile?
  • What are the exact spawn probabilities for 2 vs 4 , and must they be configurable?
  • Is undo a hard requirement, and if so, how many steps deep?
  • Do we need persistence (save/resume) or networking, or is this a single local session?
  • Should the score include only merge gains, or are there bonus/penalty rules?

What a Strong Answer Covers

  • A clean class breakdown with single-responsibility classes and clear ownership of state vs. rules vs. randomness vs. presentation.
  • The "one line-merge function + grid transforms" insight that unifies the four directions.
  • Correct handling of the at-most-one-merge-per-move rule and the move-must-change-board-before-spawn rule.
  • Correct, non-trivial win and game-over detection (game-over ≠ board full).
  • Dependency injection of the random source for deterministic testing.
  • A concrete testing strategy (exhaustive line-merge cases, all four directions, seeded randomness, win/lose/undo integration).
  • How the chosen abstractions make the extensions (undo, board size, spawn config) cheap, and the time/space complexity of a move ( O(N2)O(N^2)O(N2) ).

Follow-up Questions

  • How would you implement undo with minimal memory? Compare snapshotting the whole board vs. recording a reversible move delta, including how merges and the spawned tile complicate a pure inverse.
  • How would you detect game-over efficiently if N were large — can you maintain it incrementally instead of scanning the whole board after every move?
  • How would you adapt this design to a multiplayer or server-authoritative version where the server must validate moves and prevent cheating?
  • How would you generalize from "merge equal values into their sum" to a configurable rule (e.g., a different target tile, or Fibonacci-style merges) without touching the slide logic?
Loading comments...

Browse More Questions

More Software Engineering Fundamentals•More Asana•More Software Engineer•Asana Software Engineer•Asana Software Engineering Fundamentals•Software Engineer Software Engineering Fundamentals

Write your answer

Your first approved answer each day earns 20 XP.

Sign in to write your answer.
PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.