iOS · React Native · TypeScript · App Store

mnemo — Memory Card Game

같은 숫자 두 장을 맞추는 메모리 카드 짝 맞추기 iOS 게임. 12 / 20 / 30 / 40장 4단계 난이도와 Challenge 모드, 20+ 라이트/다크 테마, 한국어·영어, Game Center 리더보드와 일/누적 통계까지. App Store 출시.

역할
1인 개발 — 기획 · 디자인 · RN 코드 · 테마 시스템 · iOS 빌드 · 출시
플랫폼
iOS (1차) · Android 코드 베이스는 빌드 가능하나 미배포
환경
React Native 0.81 · React 19 · TypeScript · React Navigation 7 (bottom-tabs)
저장
AsyncStorage 기반 로컬 저장 (리더보드 / 누적 통계)
리더보드
Game Center (각 모드별 best time)
i18n
react-i18next + react-native-localize (한국어 / 영어)
배포
App Store
레포
a7garden/mnemo (private)

1. 앱 화면

아래 다섯 장은 App Store와 실제 앱에서 가져온 화면이다. 12장 모드 → 40장 모드 → 테마 선택 → 통계 → 결과 순서로 한 게임 사이클을 보여준다.

mnemo 12장 모드 — 3×4 카드 그리드, 파란색 카드 두 장이 공개되어 짝 매칭 중
12장 모드 — 3×4 그리드, 0~5 숫자 각 2장. 7초 타이머가 동작 중인 첫 매칭 직후.
mnemo 40장 모드 — 5×8 카드 그리드, 11/6/5 짝 매칭 진행 중
40장 모드 — 5×8 그리드, 0~19 숫자 각 2장. 11 · 6 · 5 짝이 매칭되어 공개된 상태, 나머지 카드도 곧 따라간다.
mnemo 테마 선택 — Minimal / Pastel / Earth / Sky / Dark Blue / Dark Purple / Dark Gray / Dark Navy 8종
테마 선택 모달 — Minimal · Pastel · Earth · Sky 라이트 4종 + Dark Blue · Dark Purple · Dark Gray · Dark Navy 다크 4종. 20+ 테마가 같은 모달에서 제공된다.
mnemo Personal Statistics — Daily 9 plays / 54 pairs / 21 mistakes / 28% mistake rate, Overall 동일, Statistics by Mode 12장
Personal Statistics — Daily / Overall / By Mode 3단. 오늘 플레이·짝 매칭·실수·실수율, 누적 동일 지표, 모드별 plays·best record·pairs·mistakes.
mnemo Result — 12Cards Mode 1Stage 0:07.7 / 2Stage 0:11.4 / 3Stage 0:04.3, Average 0:07.8, Back to Home
Result — 12장 모드 3스테이지 결과. Stage별 시간 + Average Time. Game Center에 자동 제출.

2. 룰 — 카드 짝 맞추기의 단순함

메모리 카드 게임은 아이부터 어른까지 아는 가장 단순한 룰 중 하나다. 그 단순함이 오히려 진입 장벽을 낮추고, "기록을 깨는 순간의 짜릿함"을 만드는 본질이 된다. 미니멀 디자인은 그 짜릿함에 집중하기 위한 선택.

3. 설계 — 5개 탭의 단순 구조

앱은 Bottom Tab 3개(Home / Statistics / Settings) + Game / Result 풀스크린 모달로 구성된다. App.tsxcurrentScreen 상태로 탭과 풀스크린 모달을 전환한다.

3.1 카드 모델

interface Card {
  id: number;        // 0..N-1, 그리드 내 유일한 식별자
  number: number;    // 0..N/2-1, 짝 매칭 키
  isFlipped: boolean;
  isMatched: boolean;
}

// Fisher-Yates 셔플로 매 게임마다 다른 레이아웃
generateCards(mode) // mode = 12 | 20 | 30 | 40
  pairCount = mode / 2
  for num in 0..pairCount-1: 2장 생성
  for i in N-1..1: j = random(0..i); swap

3.2 상태 / 데이터

리더보드와 통계는 AsyncStorage에 JSON 직렬화한다.

mnemo_leaderboard: LeaderboardEntry[]   // [{mode, time}, ...]
mnemo_statistics: GameStatistics        // totalGamesPlayed, pairsMatched,
                                       // mistakes, modeStats[mode]... 

게임이 끝나면(handleGameEnd) 다음을 순차 실행한다 — saveLeaderboard(best 갱신) → updateGameStatistics(카운터 + best time) → submitScore(Game Center). 실패해도 로컬 데이터는 유지된다.

3.3 테마 시스템

ThemeContext가 20+ 테마 프리셋을 보유한다. 각 테마는 background / surface / cardBack / cardFront / accent / text 6개 색 슬롯으로 정의되고, SettingsScreen의 모달에서 2열 그리드로 미리보기 후 즉시 적용된다. 라이트(Minimal / Pastel / Earth / Sky)와 다크(Dark Blue / Dark Purple / Dark Gray / Dark Navy) 두 그룹으로 나뉘며, 색약 사용자를 위한 High Contrast / Retro / Neon 변형도 포함된다.

3.4 다국어

react-i18next + react-native-localize로 시스템 언어에 따라 한국어/영어가 자동 선택된다. 테마 이름조차도 로컬라이즈된다 (예: Minimal vs 미니멀).

4. 기술 스택과 결정

4.1 왜 React Native인가

Game CenteriOS 디자인 언어에 자연스럽게 맞물리는 반면, 그리기 비용은 거의 0에 가까운 메모리 카드 게임 특성상 RN이 유리하다. UIKit으로 직접 그리면 보일러플레이트 대비 얻는 이득이 작다. RN 0.81 + React 19 + New Architecture로 cold start를 짧게 가져간 것이 결정적이었음.

4.2 데이터 비공개

모든 기록은 디바이스 안에만 남고 서버로 나가지 않는다. Game Center 제출은 점수만(숫자) — 어떤 카드를 어떻게 뒤집었는지는 전송되지 않는다. App Store 개인정보 명세에도 데이터 수집 없음으로 등록.

4.3 i18n 자동 감지

react-native-localize로 디바이스의 languageTag를 읽고 ko-KR / en-* 두 키로 정규화한다. SettingsScreen에서 수동 토글도 제공.

4.4 사운드

카드 뒤집기/매칭/실수/스테이지 클리어 4가지 사운드를 src/assets/sounds/에서 로드. 설정에서 음소거 가능.

5. 디자인 — 가장 적은 마찰

메모리 카드 게임은 검증된 룰을 따라야 한다. 그래서 배제할 것과 포함할 것의 경계가 명확하다.

6. 한계와 다음 단계

7. 배포 & 링크