Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HOLDEN — 프리플랍 GTO 트레이너

HOLDEN — 프리플랍 GTO 트레이너

HOLDEN = Texas Hold'em 에서 따온 이름. 포커 프리플랍 의사결정을 연습하고, 내 누수(leak)를 데이터로 분석해 어디가 약한지 보여주는 풀스택 학습 도구.

상용 트레이너(GTO Wizard 등)는 비싸고, 무료 도구는 대부분 "정답 채점"에서 끝난다. 한두 판은 재밌지만 계속 돌아올 이유가 없다. 사람을 붙잡는 건 UI가 아니라 성장 체감이라고 생각해서, 이 프로젝트는 단순 채점기가 아니라 누수 분석을 코어로 잡았다.

트레이너 화면    누수 분석 리포트


핵심 아이디어

  • 한 판은 "맞췄나?" — 즉시 채점 + "왜 이 핸드는 폴드/레이즈인가" 원리 설명
  • 여러 판은 "나는 어떤 플레이어인가?" — "너는 과하게 루즈해. 폴드해야 할 18번 중 9번을 레이즈했어"
  • 약점 포지션, 틀린 핸드 다시 풀기, XP/레벨로 성장이 보이게

즉 내 의사결정 패턴을 데이터로 모델링하는 게 목표고, 포커는 정답이 존재하는 닫힌 도메인이라 그 모델링을 연습하기 가장 깨끗한 영역이라 골랐다.

주요 기능

🎯 트레이너 6-max / 9-max, 스택 깊이(100/50/30BB)별 프리플랍 RFI 채점
📊 누수 리포트 성향(루즈/타이트), 실수 TOP 3, 포지션 마스터리, XP/레벨 — 서버에서 계산
🔁 복습 모드 틀린 핸드만 컨텍스트째 다시 출제
💡 "왜?" 설명 포지션·핸드 카테고리·스택 깊이 기반 정직한 원리 (지어낸 솔버 EV 아님)
🃏 레인지 표 13×13 핸드 차트에 내 핸드 하이라이트
🔌 graceful degradation 백엔드가 꺼져도 트레이너 자체는 동작

아키텍처

┌──────────────────────────┐      REST / JSON        ┌───────────────────────────┐
│  Next.js 16 · TypeScript │ ──────────────────────▶ │  Spring Boot 4 · Java 24  │
│  · 트레이너 루프          │  POST /api/hands         │  HandController            │
│  · 레인지 / 설명 로직     │  GET  /api/hands/report  │  HandLogService            │
│  · 누수 대시보드 UI       │  GET  /api/hands/mistakes│  StatsService (누수 분석)  │
│                          │ ◀──────────────────────  │  JPA · HandLog 엔티티      │
└──────────────────────────┘                         └─────────────┬─────────────┘
                                                                    │
                                                              ┌─────▼─────┐
                                                              │  H2 (파일) │
                                                              └───────────┘

설계 포인트: 누수 분석(성향·실수 TOP·마스터리·XP) 계산을 프론트가 아니라 StatsService(서버) 에서 한다. 단순 CRUD 가 아니라 도메인 로직이 백엔드에 있는 구조. 매 핸드는 DB 행 하나로 append-only 로 쌓이고, 리포트는 그 원본 행들을 매번 집계해서 만든다(집계값을 따로 저장하지 않아 항상 최신).

기술 스택

  • 프론트: Next.js 16 (App Router), TypeScript, CSS (글래스모피즘 다크 UI)
  • 백엔드: Spring Boot 4, Java 24, Spring Data JPA, Bean Validation
  • DB: H2 (파일 모드 — 외부 설치 불필요)
  • 테스트: Vitest (도메인 규칙 단위 테스트 13개)
  • 빌드: Gradle 9 (wrapper), npm

실행 방법

백엔드 (포트 8080)

cd backend
./gradlew bootRun

프론트엔드 (포트 3000)

cd frontend
npm install
npm run dev

→ http://localhost:3000

테스트

cd frontend && npm test     # Vitest — 핸드 카테고리 판정 규칙 검증
cd backend  && ./gradlew test   # StatsService 누수 분석 로직 검증

설계 트레이드오프 (정직한 기록)

  • 레인지 데이터는 표준 차트 근사치다. 솔버에서 받아온 정밀값이 아니다. 그래서 핸드별 "솔버 EV" 같은 가짜 수치를 지어내지 않고, 실제로 도출 가능한 원리만 설명에 넣었다. → 추후 오픈소스 솔버 export 로 교체.
  • localStorage → DB. 처음엔 단일 HTML + localStorage 로 아이디어/UX 를 빠르게 검증한 뒤, 검증된 스펙을 풀스택으로 재구성했다.
  • H2 파일 DB 로 외부 설치 없이 바로 실행. 운영 시 datasource URL 만 바꿔 Postgres 로 교체 가능.
  • 인증 없음 (단일 사용자). 세션 식별자로 그룹핑만. 계정/동기화는 다음 단계.
  • 도메인 규칙은 명시적으로. 핸드 카테고리(수티드/브로드웨이/커넥터 등) 판정을 lib/poker-rules.ts 의 이름 붙은 술어로 분리하고 단위 테스트로 고정했다.

로드맵

  • vs-오픈 디펜스 모드 — 앞에서 레이즈가 나온 상황(폴드/콜/3벳) + Pot Odds 계산
  • 깊이별·믹스 빈도를 실제 솔버 데이터로 교체
  • 인증 + Postgres + 기기 간 동기화
  • 배포 (Vercel + Railway)

About

GTO-based poker preflop trainer and real-time playstyle analysis engine

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages