openpairs is a matching pairs game. Turn cards over two at a time until every pair is found.

openpairs is free, open source, and has no tracking.

How to play
#

Rules
#

  • All cards start face down. Every face appears on exactly two cards.
  • Turn one card up, then a second. A matching pair stays face up. A mismatch turns back over after a short pause, or at once on the next tap.
  • The board is finished when every pair is found.
  • There is no timer, no score, and no way to lose.
  • Cards show shapes, with no words or numbers. Pairs match by shape, never by colour alone.

Levels
#

LevelPairs
Very Easy3
Easy6
Medium10
Hard15
Extra Hard21

The level is set under Options in the menu. Cards are never drawn smaller than a minimum size, so a small screen can hold fewer pairs than the harder levels ask for. The Options row shows the number of pairs the current screen allows, for example “Extra Hard: 18 pairs”.

Controls
#

Mouse and keyboard, on computers and in desktop browsers:

InputAction
Click a cardTurn it over
Arrow keys, WASDMove the highlight
Enter / SpaceTurn over the highlighted card
EscapeBack to the menu. The game can be resumed
Alt+EnterToggle fullscreen
Up / Down, Enter / SpaceMenu navigation. Left / Right change the level in Options

Touch, on phones, tablets, and mobile browsers:

GestureAction
Tap a cardTurn it over
Tap above the cards, or two-finger tapBack to the menu. The game can be resumed
Tap a menu rowChoose it. In Options, a tap cycles the value
Swipe up / down in the menuMove the selection. Left / right cycles a value in Options

Where to play
#

  • Browser: play it here. Nothing to install.
  • iPhone and iPad: on the App Store. iOS 15 or later.
  • Android: install the APK from the latest release. It is not on Google Play.
  • Windows, macOS, Linux: download the archive for your system from the latest release.
Download openpairs on the App Store

Technical details
#

Source code: github.com/dannyheskett/openpairs, MIT license.

Code
#

  • Written in C.
  • The rules (src/game.c) and the board layout (src/layout.c) are platform-independent. Every platform uses them unchanged. Unit tests cover both and need no window.
  • Drawing, input, and audio use raylib 6.0 on Windows, macOS, Linux, Android, and the web. iOS uses its own Metal and UIKit backend with no raylib.
  • The 21 card faces are drawn shapes. Sound effects are synthesized at startup. The Nunito typeface is embedded in the binary. There are no asset files.
  • The browser version is the same C compiled to WebAssembly with Emscripten.

Layout
#

One layout serves every screen. Each frame the grid of cards is sized to the window, so it works in a desktop window and in both orientations on phones and tablets. The number of pairs is fixed when a game starts, so rotating re-fits the same board without reshuffling it. The minimum card size scales with the short edge of the screen rather than a fixed pixel count.

Recording
#

Desktop builds record the session to an H.264 MP4 file, one video frame per rendered frame, with no external tools. Turn on Record in the menu, or start with --record or --record <file>.mp4. Mobile and web builds do not include the recorder.

Builds and releases
#

Every push to main that changes the code builds and publishes a release: Linux x86-64, macOS universal, Windows x64 and x86, an Android APK and App Bundle, an iOS .ipa, and the WebAssembly bundle. The .ipa is the App Store build and cannot be sideloaded. Build instructions are in the README.