iOS · React Native · TypeScript · App Store
mnemo — Memory Card Game
같은 숫자 두 장을 맞추는 메모리 카드 짝 맞추기 iOS 게임. 12 / 20 / 30 / 40장 4단계 난이도와 Challenge 모드, 20+ 라이트/다크 테마, 한국어·영어, Game Center 리더보드와 일/누적 통계까지. App Store 출시.
1. 앱 화면
아래 다섯 장은 App Store와 실제 앱에서 가져온 화면이다. 12장 모드 → 40장 모드 → 테마 선택 → 통계 → 결과 순서로 한 게임 사이클을 보여준다.
2. 룰 — 카드 짝 맞추기의 단순함
메모리 카드 게임은 아이부터 어른까지 아는 가장 단순한 룰 중 하나다. 그 단순함이 오히려 진입 장벽을 낮추고, "기록을 깨는 순간의 짜릿함"을 만드는 본질이 된다. 미니멀 디자인은 그 짜릿함에 집중하기 위한 선택.
- 짝 매칭 — 카드를 두 장 뒤집어 같은 숫자면 매칭 처리, 아니면 다시 뒤집기.
- 4단계 난이도 — 12(0~5) → 20(0~9) → 30(0~14) → 40(0~19). 카드 수가 늘수록 그리드가 3×4 → 4×5 → 5×6 → 5×8로 확장.
- Challenge 모드 — 40장 모드와 별도의 시간 제한 챌린지. 보너스 시간 시스템.
- Game Center — 각 모드별 best time을 제출. 친구와 비교.
3. 설계 — 5개 탭의 단순 구조
앱은 Bottom Tab 3개(Home / Statistics / Settings) +
Game / Result 풀스크린 모달로 구성된다. App.tsx가
currentScreen 상태로 탭과 풀스크린 모달을 전환한다.
- HomeScreen — 모드 선택 (12/20/30/40 + Challenge) + 모드별 best time 미리보기.
- GameScreen — 카드 그리드, 0.1초 단위 타이머, 매칭 시 시각/촉각 피드백.
- ResultScreen — Stage별 시간 + Average Time + Game Center 제출.
- StatisticsScreen — Daily / Overall / By Mode 3단 통계.
- SettingsScreen — 언어, 테마, 사운드, 게임 센터 로그인, 크레딧.
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 Center와 iOS 디자인 언어에 자연스럽게 맞물리는 반면, 그리기 비용은 거의 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. 디자인 — 가장 적은 마찰
메모리 카드 게임은 검증된 룰을 따라야 한다. 그래서 배제할 것과 포함할 것의 경계가 명확하다.
- 포함 — 카드 / 타이머 / 매칭 피드백 / Game Center / 통계 / 테마.
- 배제 — 일일 미션, 광고, 팝업, 코인, 계정, 클라우드 동기화. 기록은 Game Center 한 곳으로 충분.
- 테마 우선 — 같은 게임이라도 색이 바뀌면 다시 플레이하고 싶어진다. 20+ 프리셋의 진정한 비용은 디자인 토큰 시스템 1개.
6. 한계와 다음 단계
- 사운드 — 현재 4가지 효과음만. 배경음악과 매칭 시 시각 효과(파티클)는 후속.
- Challenge 모드 확장 — 시간 제한 외 라운드 클리어 기반 변주(예: 30초 안에 5판 연속 클리어).
- 접근성 — VoiceOver 라벨은 일부 화면에만 등록. 다음 업데이트에서 전면 보강.
- Android — RN 코드 베이스는 Android 모듈을 포함하지만 정식 빌드/배포는 미진.
- 멀티 디바이스 동기화 — Game Center가 best time의 공통 분모. 다른 통계(누적 plays, mistake rate)는 디바이스 종속.
7. 배포 & 링크
App Store mnemo
공식 배포. 한국어/영어. © 2025 0010capacity. logit과 동일한 Apple Developer 계정으로 등록.
apps.apple.com/kr/app/mnemo-memory-card-game/id6752640768 a7garden/mnemo private repo
소스 트리. React Native 0.81 + React 19 + TypeScript. 6 screens (Home / Game / Result / Statistics / Settings / Leaderboard). 비공개 — 외부 공개는 정책상 불가, 앱스토어 빌드로 동일한 결과물을 확인 가능.
github.com/a7garden/mnemo