Skip to content
yjworksPublic

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

딴짓

잠깐 딴짓하기 좋은 게임 모음 — 오목 · 장기 · 리버시 · 윷놀이 · 스도쿠 · 지뢰찾기 · 노노그램 · 솔리테어 · 테트리스 · 벽돌깨기 · 2048 · 꼬들

https://yjworks.github.io/games/

서버도 계정도 없습니다. 진행 상황과 기록은 브라우저(localStorage)에만 저장되고, 한 번 열어 본 뒤에는 네트워크 없이도 실행됩니다(PWA).

/                       게임 네비게이터(허브)
/games/omok/       오목      /games/minesweeper/  지뢰찾기   /games/tetris/    테트리스
/games/janggi/     장기      /games/nonogram/     노노그램   /games/breakout/  벽돌깨기
/games/reversi/    리버시    /games/solitaire/    솔리테어   /games/2048/      2048
/games/yut/        윷놀이    /games/sudoku/       스도쿠     /games/kkodle/    꼬들

허브에서 분류(보드 · 퍼즐 · 액션 · 데일리)로 걸러 볼 수 있고, 키보드가 있으면 숫자키로 바로 들어갑니다 (숫자키·방향키 안내는 마우스·키보드가 있는 기기에서만 보이고, 터치 화면에서는 숨깁니다 — base.css의 .kbd-only/.touch-only).

게임

게임 분류 특징
오목 보드 15×15, 좌표 표시, 착수 미리보기, 승리 라인 강조. AI는 즉승/즉방 + 열린형태 평가로 최대 10수를 읽습니다(1.6초).
장기 보드 차림 4종·진영 선택, 점수제(한 덤 1.5), 기보. AI는 MVV-LVA 정렬 + 정지탐색으로 최대 5수(2.5초).
리버시 보드 착수 가능 위치 표시, 모서리·기동력·확정석 평가, 종반 16칸 완전탐색(2.5초).
스도쿠 퍼즐 유일해 보장 생성, 메모·자동메모·되돌리기·힌트, 실수 제한.
지뢰찾기 퍼즐 추측이 필요 없는 판만 출제 — 생성한 배치를 솔버로 끝까지 풀어 보고 통과한 것만 내보냅니다.
노노그램 퍼즐 줄 논리만으로 풀리는 문제만 출제 — 유일해가 보장됩니다. 밀어서 칠하기, 되돌리기.
솔리테어 퍼즐 클론다이크. 한 장/세 장 뽑기, 두 번 눌러 자동 이동, 되돌리기, 자동 완성.
테트리스 액션 SRS 회전 + 월킥, 7-bag, 홀드, 고스트, 락 딜레이, T-스핀/백투백/콤보.
윷놀이 보드 도개걸윷모와 뒤도, 지름길·업기·잡기까지. 모서리에 정확히 멈춰야 지름길을 탑니다. AI 3단계와 2인 대국.
벽돌깨기 액션 패들 어디에 맞느냐로 각이 갈리고, 빠른 공도 벽돌을 뚫지 않습니다. 아이템 3종과 판마다 다른 배치.
2048 액션 타일이 미끄러지는 연출, 되돌리기, 최고 타일 기록, 2048 이후 계속하기.
꼬들 데일리 두 글자 한글 낱말을 자모 단위로 채점. 하루 한 문제 + 무한 모드, 연속 일수 기록. IME 없이도 되는 한글 조합 자판 내장.

오늘의 문제는 꼬들·스도쿠·노노그램·지뢰찾기 네 곳에 있습니다. 서버가 없으므로 기기 날짜를 시드로 삼아 만들며, 같은 날이면 누가 열어도 같은 문제가 나옵니다.

모든 게임에 튜토리얼(첫 방문 자동 · 이후 ? 키) 과 서사가 있고, 진행 중인 대국은 자동 저장되어 허브에서 “이어하기”로 돌아갈 수 있습니다.

설계

모바일 퍼스트로 만들었습니다. 기본 레이아웃이 세로 화면 기준이고, 넓은 화면에서 사이드 패널이 열립니다. 터치 목표는 최소 44~52px, 하단 조작부는 env(safe-area-inset-bottom)을 반영합니다.

게임끼리 공유하는 코드는 src/shared/(공통 레이어)에 모여 있습니다.

모듈 역할
registry.ts 게임 목록·메타데이터·서사. 허브와 각 게임이 같은 정의를 참조
storage.ts games:<gameId>:<key> 네임스페이스 localStorage 래퍼 (저장 실패해도 게임은 계속 동작)
progress.ts “이어하기” 요약 — 허브 카드에 표시
records.ts 최고 기록 (점수형/시간형 모두 지원)
stats.ts AI 대전 전적
prefs.ts 전역 설정(효과음) — 모든 게임이 공유
sound.ts WebAudio 합성 효과음. 오디오 파일 없음
tutorial.ts 튜토리얼 자료형 + 최초 1회 자동 표시 여부
daily.ts 날짜 시드로 정하는 오늘의 문제 + 연속 일수 기록
color.ts 색 밝기·투명도 (캔버스 그러데이션용)
react/GameShell.tsx 공통 상단바(허브 링크·제목·도움말·효과음) + 튜토리얼
react/GameMark.tsx 게임마다 하나씩 있는 표식(SVG). 허브 카드와 상단바가 같은 그림을 씁니다
react/useKeys.ts 전역 단축키
dom/shell.ts, dom/tutorial.ts React를 쓰지 않는 게임(스도쿠)용 같은 기능
pwa.ts 서비스 워커 등록

게임을 새로 추가하는 방법은 docs/ADDING_A_GAME.md, 외부 라이브러리(MediaPipe 등) 반입 규칙은 docs/THIRD_PARTY_ASSETS.md를 보세요.

개발

npm install
npm run dev        # 개발 서버 (허브: /, 게임: /games/<id>/)
npm test           # 규칙 엔진 테스트 (vitest, 190여 개)
npm run typecheck
npm run build      # dist/ 생성 (허브 + 게임 12개 + 서비스 워커)
npm run preview

배포

main에 푸시하면 GitHub Actions가 빌드해 gh-pages 브랜치로 배포합니다. base가 상대 경로(./)라서 계정 이름이나 저장소 이름이 바뀌어도 그대로 동작합니다. 서비스 워커의 경로도 전부 상대 경로입니다.

앱이 도는 데 필요한 주소는 매니페스트의 id(/games/) 하나뿐입니다(링크 미리보기용 canonical·og:url에는 https://dibrain.dev/games/...가 적혀 있어, 주소를 옮기면 같이 고칩니다). 앱 식별자는 설치된 앱을 가리키는 이름이라 고정돼 있어야 합니다 — 빼 두면 start_url에서 파생되는데, 그러면 start_url을 손대는 순간 다른 앱이 되어 홈 화면에 아이콘이 두 개 생깁니다. /games/가 아닌 경로로 옮긴다면 이 값도 같이 옮겨야 합니다.

기록은 주소(오리진)에 매여 있습니다. 배포 주소를 옮기면 localStorage가 새로 시작하고 설치해 둔 PWA도 따로 잡힙니다 — 옮기기 전에 알아 둘 것.

오프라인

  • 서비스 워커가 빌드 산출물 전체를 미리 캐시합니다(vite.config.ts의 pwaPlugin).
  • 두 번째 방문부터는 네트워크 없이 실행되고, 홈 화면에 설치하면 앱처럼 열립니다.
  • 외부 CDN을 쓰지 않습니다. 폰트·아이콘·효과음까지 전부 저장소 안에 있습니다.
  • 글꼴 Pretendard는 public/vendor/fonts/에 있습니다. pretendard.css만 미리 캐시하고, 조각 파일(woff2 92개)은 화면에 필요한 것만 처음 쓸 때 받아 games-fonts-v1 캐시에 둡니다(다음부터 네트워크를 보지 않음).
  • 같은 주소(dibrain.dev)를 쓰는 다른 앱의 캐시는 건드리지 않습니다. 옛 캐시를 지울 때 games-로 시작하는 것만 지웁니다.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages