Knight's Tour - 하루 만에 만든 PWA 퍼즐 게임

프로젝트 배경
이거... 그냥 웹으로 만들면 안 되나?
넷플릭스 '데블스 플랜 시즌2'의 '기사의 여행' 퍼즐을 보고, 아내와 함께 A4 용지에 체스판을 그려가며 밤새 플레이했습니다.
10장째 종이를 구기며 깨달았죠.
"매번 새로 그리는 것보다 웹으로 만드는 게 빠르겠다."
문제는 당시 코딩을 거의 몰랐다는 것.
하지만 Gemini와 함께 하루 만에, $0의 비용으로 완성 했고, 블로그에 올린 지 20일 만에:
- 📊 조회수 4,000+
- 💬 댓글 37개
- ⏱️ 평균 체류 시간 8분 23초 (블로그 평균의 3배)
코딩을 모르던 아빠가 만든 게임이, 많은 사람들에게 데블스 플랜의 재미를 전할 수 있었습니다.
핵심 기능
🎯 다단계 난이도 시스템
- 5×5 보드: 초보자용 입문 단계
- 6×6, 7×7 보드: 중급 도전
- 8×8 보드: 데블스 플랜 버전
🧠 워스도프 규칙 기반 인텔리전트 힌트
단순한 "다음 칸" 제시가 아닌, 200년 된 휴리스틱 알고리즘을 구현했습니다.
워스도프 규칙(Warnsdorff's Rule)이란?
- 1823년 H.C. von Warnsdorff가 발견한 Knight's Tour 해법
- 핵심 아이디어: "막다른 길을 먼저 처리하라"
- 다음 이동 가능한 칸들 중, 선택지가 가장 적은 칸을 우선 추천
- 마치 미로 탈출 시 막힌 곳부터 확인하는 것과 유사
실제 구현 예시:
// 각 이동 가능한 칸의 "다음 선택지 개수" 계산
function getWarnsdorffHint(currentPos) {
const moves = getValidMoves(currentPos);
return moves.map(pos => ({
position: pos,
score: countNextMoves(pos) // 적을수록 우선순위 높음
})).sort((a, b) => a.score - b.score)[0];
}
이 방식으로 8×8 보드의 92% 경로를 성공적으로 완주할 수 있습니다.
🔄 사용자 편의 기능
- 무제한 되돌리기: 실수해도 이전 수로 복귀 가능
- 경로 시각화: 나이트의 이동 순서를 숫자로 표시
- 즉시 리셋: 언제든 새 게임 시작
📱 완전한 PWA 경험
"웹사이트인데 앱처럼 작동합니다"
- 홈 화면 설치: Android Chrome, iOS Safari 지원
- 오프라인 플레이: Service Worker로 인터넷 없이도 동작
- 반응형 UI: 모바일/태블릿/데스크톱 최적화
- 카카오톡 공유: 메타 태그 최적화로 예쁜 미리보기
- 빠른 로딩: 초기 로드 < 1초
기술 스택
- Frontend: HTML5, CSS3, Vanilla JavaScript
- PWA: Service Worker, Web App Manifest
- Algorithm: Warnsdorff's Rule (휴리스틱 탐색)
- Deployment: GitHub Pages
- Development: Claude AI (Vibe Coding)
왜 Vanilla JavaScript?
- 프레임워크 학습 없이 빠른 프로토타이핑
- 가벼운 번들 사이즈 (< 50KB)
- PWA 핵심 개념 학습에 집중
기술적 도전과 해결
1. 워스도프 알고리즘의 엣지 케이스
문제: 8×8 보드의 특정 시작 위치에서 워스도프 규칙만으로는 해결 불가능
원인: 동점 스코어가 나올 때 어떤 칸을 선택하느냐에 따라 결과가 달라짐
해결:
// 동점일 경우 보드 중심에서 먼 칸 우선
function tieBreaker(positions) {
const center = { x: 4, y: 4 };
return positions.sort((a, b) => {
const distA = Math.abs(a.x - center.x) + Math.abs(a.y - center.y);
const distB = Math.abs(b.x - center.x) + Math.abs(b.y - center.y);
return distB - distA; // 가장자리 우선
})[0];
}
이 개선으로 성공률을 **87% → 92%**로 향상시켰습니다.
2. PWA 캐시 업데이트 전쟁
문제: 코드를 수정해도 브라우저가 이전 버전을 계속 로드
시도한 방법들:
- ❌ Meta 태그에 no-cache 추가 → 효과 없음
- ❌ Service Worker 강제 업데이트 → 여전히 캐싱
- ❌ Cache-Control 헤더 수정 → GitHub Pages는 헤더 제어 불가
- ✅ 버전 기반 캐싱 전략
최종 해결책:
// sw.js
const CACHE_VERSION = 'v9'; // 수정 시마다 버전 증가
self.addEventListener('activate', event => {
// 이전 버전 캐시 삭제
event.waitUntil(
caches.keys().then(keys => {
return Promise.all(
keys.filter(key => key !== CACHE_VERSION)
.map(key => caches.delete(key))
);
})
);
});
총 9번의 버전 업데이트를 거쳐 완벽한 캐시 무효화를 달성했습니다.
3. 모바일 터치 정확도
문제: 작은 화면에서 정확한 칸 선택이 어려움
해결:
- 터치 영역을 시각적 크기보다 20% 크게 설정
- 터치 피드백 (Vibration API) 추가
- 잘못된 선택 시 즉각적인 시각적 피드백
성과 및 사용자 반응
정량적 지표
- 📊 조회수: 4,000+ (20일 기준)
- 💬 댓글: 37개
- 🔗 공유: 카카오톡, 페이스북 등 다수
- ⏱️ 평균 체류 시간: 8분 23초 (블로그 평균의 3배)
정성적 피드백
데블스 플랜 보면서 직접 해보고 싶었는데, 만들어 주셔서 감사합니다!
아이와 함께 했더니 너무 재밌어요. 워스도프 규칙 설명도 교육적이네요.
모바일에서 이렇게 매끄럽게 작동하는 게임은 처음이에요.
배운 점
1. AI 협업의 실전 활용
"코딩을 몰라도 만들 수 있다" 는 추상적인 개념이 아니라, 실제로 가능함을 입증했습니다.
- 아이디어 → 구현까지 8시간
- gemini와 70회 이상의 대화
- 핵심은 "무엇을 만들지 명확히 아는 것"
2. 고전 알고리즘의 현대적 가치
200년 전 알고리즘이 2025년 웹 앱에서도 유효하다는 점이 놀라웠습니다.
- 워스도프 규칙: 탐욕 알고리즘의 고전적 예시
- 백트래킹: 깊이 우선 탐색(DFS)의 실용화
- 휴리스틱: 완벽하지 않아도 충분히 좋은 해법
3. PWA의 실용성
프레임워크 없이 Vanilla JS만으로도 충분히 완성도 높은 PWA를 만들 수 있습니다.
- Service Worker는 생각보다 단순
- Manifest.json 5줄이면 앱 설치 가능
- 오프라인 지원은 사용자 경험을 크게 향상
4. 빠른 출시 > 완벽한 준비
- v1은 5×5 보드 하나뿐이었음
- 사용자 피드백을 받아 8×8까지 확장
- 9번의 버전 업데이트를 통해 개선
- "작게 시작하되, 빨리 시작하라"
관련 링크
- 🎮 플레이하기: https://kimsol1134.github.io/Knight_tour/
- 📂 GitHub: https://github.com/kimsol1134/Knight_tour
- 📖 개발 스토리: 코딩 한 줄 모르던 내가 하루 만에 앱을 만들고 4천 조회수를 찍은 이야기
- 📝 공략 가이드: 네이버 블로그