교수님 강의를 실시간 음성인식(STT)으로 듣고, 핵심 전공 용어만 뽑아 떨어뜨리는 음성 기반 산성비 타자 게임. 수업은 놓치기 싫고, 손은 심심할 때를 위해 만들었습니다.
🎮 데모: https://oofrog.github.io/class-typing-game/
수업이 집중 안 될 때, 딴짓은 하고 싶지만 강의 내용은 놓치기 싫을 때 — 교수님 목소리를 마이크로 듣고 있다가 중요한 단어만 화면 위에서 비처럼 떨어뜨려 주는 타자 게임입니다.
조사·어미·습관어("자,", "그러면", "~입니다")는 알아서 걸러지고, 핵심 키워드만 남아서 떨어집니다. 떨어지는 단어를 하단 입력창에 그대로 타이핑하면 점수가 오르고, 바닥에 닿으면 목숨(❤️)이 깎입니다.
외부 AI API를 전혀 쓰지 않고 브라우저 안에서 음성인식 + 자연어 처리를 모두 처리하는 게 핵심입니다. (Zero-Backend / No-API)
🎙️ 교수님 음성
│ Web Speech API (STT, ko-KR)
▼
📝 인식된 문장 "오늘 배울 메모리가 아주 중요합니다."
│ Local NLP 파이프라인 (5단계)
▼
🔑 핵심 단어 ["메모리", "아주", "중요"]
│ 순차 스폰 (0.9초 간격)
▼
🌧️ 화면에 낙하 → 타이핑으로 파괴 → 점수 / 목숨
외부 LLM 없이, 순수 정규식과 규칙 기반으로 핵심 단어를 추출합니다.
| 단계 | 처리 | 예시 |
|---|---|---|
| 1. 토큰화 | 띄어쓰기 기준 분리 | "메모리가 아주 중요합니다" → ["메모리가", "아주", "중요합니다"] |
| 2. 특수기호 제거 | 구두점(. , ? ! ; : 등) 제거 |
"중요합니다." → "중요합니다" |
| 3. 조사·어미 제거 | 정규식으로 한국어 조사/어미 절단 | "메모리가" → "메모리", "중요합니다" → "중요" |
| 4. 길이 필터링 | 1글자 이하 탈락 | "자", "그" 제거 |
| 5. 불용어 필터링 | 강의 습관어·접속사 등 제거 | "그리고", "일단", "여러분" 제거 |
- 실시간 음성인식 자막 — 인식 중인 문장을 우측 패널에 즉시 표시 (
interimResults) - 마이크 무한 수신 — 침묵으로 STT가 끊겨도
onend에서 자동 재시작 - 순차 스폰 — 긴 문장이 들어와도 단어가 한꺼번에 겹치지 않고 약 0.9초 간격으로 줄지어 낙하
- 스마트 매칭
- 화면에 없는 단어를 입력하면 무시
- 같은 단어가 여러 개면 가장 아래쪽(곧 바닥에 닿을) 단어부터 제거
- 목숨 시스템 — ❤️ 5개로 시작, 단어가 바닥에 닿으면 1개 차감, 0이 되면 게임 오버
- 동적 난이도 — 점수가 오를수록 낙하 속도 증가 (
속도 = 기본속도 + 랜덤 + 점수 × 가중치) - 게임 오버 / 다시 시작 — 최종 점수 모달 + 상태 초기화 후 재시작
- 점수 획득 이펙트 — 단어 파괴 시
+1플로팅 애니메이션 - 디버그 패널 — 마이크가 없는 환경(도서관 등)을 위해 텍스트를 수동 주입해 테스트 가능
- Frontend: HTML5, CSS3, Vanilla JavaScript (ES6+)
- 음성인식: Web Speech API (
webkitSpeechRecognition) - 자연어 처리: 자체 구현 로컬 NLP (정규식 + 규칙 기반)
- 렌더링/물리:
requestAnimationFrame - 배포: GitHub Pages
- 의존성: 없음 (프레임워크·외부 API·빌드 도구 전부 미사용)
class-typing-game/
├── index.html # 게임 레이아웃 (캔버스 / 자막 / 입력창 / 모달)
├── style.css # 다크 + 네온 그린 테마
├── script.js # STT, NLP 파이프라인, 게임 엔진 전체 로직
├── research.md # 기술 스택·아키텍처·제약 사항 정의 (기획 문서)
└── plan.md # TDD 기반 Phase별 작업 체크리스트
processText(text)— 5단계 NLP 필터링 파이프라인testNLPEngine()—console.assert기반 NLP 단위 테스트 (TDD)Word클래스 — 떨어지는 단어 한 개의 위치·속도·DOM 관리GameEngine클래스 — 단어 큐, 순차 스폰, 낙하 루프, 매칭, 목숨/점수, 게임오버·리셋- STT 모듈 —
initSpeechRecognition,startSpeechRecognition, 자동 재시작 로직
이 프로젝트는 처음으로 바이브코딩(Vibe Coding)을 시도한 작업물입니다. 전통적인 개발(요구사항 → 직접 타이핑 → 수동 디버깅) 대신, 규칙을 문서로 정의해 두고 AI에게 코드 작성을 맡기고, 결과를 검증해 다시 지시하는 방식으로 진행했습니다.
- 기획 — Gemini로 아이디어를 구체화하고
research.md(기술 스택·제약),plan.md(TDD 작업 체크리스트)를 먼저 작성 - 지시 — "research.md와 plan.md를 읽고 목표와 TDD 방식을 파악한 뒤 Phase 1부터 시작해 줘"라고 시키고, 이후로는 거의 "해줘"만으로 Phase를 하나씩 진행
- 검증 — 각 Phase마다 동작을 확인하고
plan.md체크박스를 업데이트
- 브라우저 호환성 — 평소 쓰던 Brave에서 보안 정책상 Web Speech API가 동작하지 않음. 설계 단계에서 놓쳤던 부분이라 크롬 전용으로 정리.
- API 대신 로컬 NLP — 처음엔 AI API로 핵심 단어를 추출하려 했으나 API 오류 발생. 결국 외부 API를 걷어내고 정규식·규칙 기반의 자체 NLP로 전환 → 오히려 Zero-Backend라는 깔끔한 아키텍처로 귀결.
- 코드를 바로 짜기 전에 제약 사항과 작업 단위를 문서로 못 박아두면 AI 협업의 품질이 크게 올라간다.
- 외부 의존성(API·프레임워크)을 줄이는 선택이 디버깅과 배포를 훨씬 단순하게 만든다.
- 크롬에서만 동작 — Web Speech API 지원/정책 차이로 다른 브라우저는 미지원
- 음성인식 정확도 — 브라우저 내장 STT에 의존하므로 발음·소음 환경에 영향을 받음
- 규칙 기반 NLP — 조사/어미/불용어가 하드코딩이라 학습형 모델보다 예외 처리에 한계가 있음
강준우 · 한양대학교 ERICA 소프트웨어융학대학 학회 HY-End 세미나 발표 (AI · Vibe Coding · Game)