[ project / android ]

Open-source arithmetic deduction puzzle

NumPairs

NumPairs is a native Android puzzle where players complete hidden expressions by deducing how numbers from a strip pair across a result grid.

NumPairs puzzle anatomyAn illustrative number strip feeds a result grid. A pair such as 2 and 3 creates an addition result of 5 and a multiplication result of 6.PUZZLE LOOPNUMBER STRIP1 2 ? 4 4 ? 7 9hidden values are deducedpair factsRESULT GRID? + ?5? × ?6one pair → one sum + one product
An illustrative view of the core rule: a solution pair contributes one addition tile and one multiplication tile.

A puzzle built around deduction

NumPairs turns arithmetic into a constraint-solving puzzle. The player sees a strip of positive integers in ascending order and a board of visible results. The expressions that produced those results are hidden, so progress comes from finding consistent pairings rather than guessing a sequence of moves.

Each solution pair is used twice: once to produce a sum and once to produce a product. For example, the pair(2, 3) accounts for result tiles 5and 6. A strip entry is a distinct game element even when another entry displays the same numeric value.

What a completed puzzle means

  1. Reveal the strip. Deduce every hidden value while preserving the strip's ordering rules.
  2. Resolve the grid. Assign operands and operators to the hidden expressions beneath each known result.
  3. Validate the pairings. Use each strip entry once for an addition and once for a multiplication across the board.

Play options

The current app groups generated play into Quick and Classic, while keeping the exact puzzle-size families explicit in the domain. Daily Challenge adds a deterministic, device-local challenge without requiring an account or a server.

  • Quick: shorter generated challenges.
  • Classic: the original full-board challenge sizes.
  • Daily Challenge: one reproducible local-date puzzle and completion history.

A calm, complete puzzle product

NumPairs is designed as a polished mobile puzzle rather than a collection of isolated mechanics. The experience starts with a clear entry point, teaches the rules through a guided tutorial, and then gives players distinct ways to return: Quick for a shorter session, Classic for the full board, and Daily Challenge for a local-date ritual.

The product deliberately avoids pressure systems that do not support the puzzle. There is no account, advertising, analytics, or developer-operated server behind the core loop. Progress, preferences, and Daily history belong to the local installation, keeping the game available without a network dependency.

Calm challenge

A thoughtful arithmetic puzzle that rewards deduction without turning the experience into an arcade or an educational exercise.

Clarity first

The board, number strip, and completion feedback carry the experience; every other element stays in service of solving.

A complete product

Tutorial, Quick, Classic, Daily Challenge, personalization, and local progress form one coherent app rather than isolated features.

Respectful by default

No account, ads, analytics, or developer-operated gameplay service is required to play.

A quiet, shape-first visual language

The visual direction aims for something elegant, minimalist, intelligent, calm, modern, and premium. It avoids the usual shortcuts of a childish, arcade-like, or overly educational number game. The interface should feel like a considered product, while remaining approachable enough for a casual puzzle session.

The board is the protagonist. Spacing comes before decoration, typography before color, and hierarchy before effects. The design system uses Material 3 as a platform foundation but adds its own decisions for surfaces, states, density, and reusable components instead of looking like a raw template.

A logo built from the unresolved expression

The mark reduces the game to its universal idea:? [+×] ?. The question marks represent unknown operands and the central operator group carries the two core operations, addition and multiplication.

Its identity is shape-first rather than color-first, so it remains recognizable in monochrome, across themes, and at launcher-icon size. The visual language stays flat and legible: no gradients, heavy shadows, decorative containers, or detail that competes with the puzzle.

Simple architecture, deliberate constraints

The engineering decisions follow the product's scale and purpose. NumPairs is a native Android app written in Kotlin; Android is the natural medium for a focused mobile puzzle and the native approach keeps the first product direct to build, debug, and iterate.

Jetpack Compose provides a declarative UI suited to a dynamic board, a compact number strip, and state-driven feedback. The puzzle rules remain separate from the UI so gameplay can be reasoned about and tested without making the screen the source of truth.

Self-contained product

The app is intentionally a single local product. It has no remote gameplay API, account system, or external service required to start or complete a puzzle.

Local persistence

Preferences DataStore stores the versioned generated-session aggregate and the separate Daily Challenge aggregate. A relational database is unnecessary for these small, application-private state boundaries.

Recoverable progress

The exact puzzle and current progress are persisted before a session is presented as ready, so resuming does not silently regenerate a different challenge after process death.

Validated content

Generated puzzles start from a solved model, are masked for play, and pass shared validation before they reach the player. Explicit seeds and limits keep the process reproducible.

From product intent to merged change

NumPairs is developed through a documentation-first workflow that keeps product intent and implementation detail connected. The process is deliberately incremental: every level adds enough clarity for the next decision without turning planning into a substitute for delivery.

  1. Agile board -> GitHub Project

    A GitHub Project makes priorities, status, stage, and delivery context visible across the product.

  2. Functional refinement -> Milestone

    A milestone defines the product outcome, scope, success criteria, delivery stages, and explicit exclusions.

  3. Technical refinement -> atomic GitHub Issues

    The milestone is divided into dependency-ordered GitHub Issues, each with one observable outcome, then refined with context, approach, and acceptance criteria.

  4. Branch implementation

    The change is implemented in a focused branch while unrelated product work and repository changes remain separate.

  5. Review and merge

    Validation, review, and a Pull Request provide the delivery gate before the change is merged into the main branch.

This workflow creates a traceable path from an idea on the board to a reviewed change in the main branch, while keeping the product small enough to evolve one meaningful decision at a time.

NumPairs is a small game with a clear point of view: a calm puzzle experience, a restrained visual language, and a delivery process that makes each product decision visible.