Files
joke-app/docs/games/las-vegas.md
EJClaw f4d63e1544 docs: 온라인 보드게임 사이트 계획서 (공통 14편 + 게임 26종)
- 개요, 조사(BGA·한국 인기 보드게임·UI/UX), 아키텍처, 실시간 프로토콜,
  안정성·보안, 계정, 로비·방, UI/UX, 데이터 모델, 게임 엔진, 테스트,
  배포·운영, 로드맵(M0~M9), 사용자 결정 항목
- 게임별 규칙·엔진 설계·UI·테스트 체크리스트 26종

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 04:18:29 +09:00

175 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 라스베가스 주사위 (`las-vegas`)
> 마일스톤: M7 · 인원: 최소 2 ~ 최대 5명 · 예상 시간: 약 20~30분 · 난이도: 쉬움
## 1. 개요
- 각자 주사위 8개를 굴려, 나온 눈 하나를 골라 그 눈의 주사위를 모두 같은 번호(1~6) 카지노에 놓는다. 라운드가 끝나면 카지노마다 주사위가 가장 많은 사람부터 높은 지폐를 가져가는데, 개수가 같은 사람끼리는 모두 무효가 된다. 4라운드 뒤 돈이 가장 많은 사람이 이긴다.
- Rüdiger Dorn의 보드게임(2012년, alea/Ravensburger)으로, 한국 보드게임 카페에서 "라스베가스"라는 이름으로 잘 알려진 가족용 주사위 게임이다. 규칙이 짧고 동점 무효 규칙 덕분에 역전이 잦아 어린이·어르신이 함께 하기 좋다.
- 인원 근거: 원작 규칙서 기준 2~5명(색깔별 주사위 5세트). 2~4명은 중립(흰색) 주사위 변형 규칙이 공식 규칙서에 포함돼 있다.
## 2. 모드와 옵션
| 옵션 키 | 설명 | 선택지 | 기본값 |
|---|---|---|---|
| `rounds` | 라운드 수 | 3, 4, 5 | 4 |
| `neutralDice` | 중립(흰) 주사위 변형 | `auto`(2명일 때만 사용, 1인당 4개), `on`(2명 1인당 4개, 3~4명 1인당 2개), `off` | `auto` |
| `hideMoney` | 다른 사람이 번 돈 금액을 숨김(원작: 지폐를 뒤집어 둠) | `true`(장 수만 공개), `false`(금액 공개) | `true` |
| `turnSeconds` | 한 차례(굴리기+놓기) 제한 시간 | 20, 30, 60, `null` | 30 |
옵션 검증: 5명일 때 `neutralDice = on`은 허용하지 않는다(흰 주사위가 5번째 색이라 남지 않음). `auto`는 5명에서 자동으로 꺼진다.
## 3. 구성물
- 주사위 40개: 5색 × 8개. 2~4명이면 쓰지 않는 색 1세트(8개)를 "중립(흰색)" 주사위로 쓴다.
- 카지노 6곳: 1~6번(원작은 실제 카지노 이름이 붙어 있으나 우리는 "1번 카지노"~"6번 카지노" 또는 자체 이름을 쓴다).
- 지폐 54장(단위: 만 달러, 게임 안 가상 돈):
| 금액 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|
| 장 수 | 6 | 8 | 8 | 6 | 6 | 5 | 5 | 5 | 5 |
합계 54장, 총 250만 달러.
## 4. 준비(셋업)
1. 지폐 54장을 섞어 비공개 더미(`pile`)를 만든다.
2. 카지노 1번부터 6번까지 순서대로, 더미 위에서 한 장씩 꺼내 그 카지노에 놓되 그 카지노의 지폐 합이 5(=5만 달러) 이상이 될 때까지 계속 놓는다. 카지노의 지폐는 금액 내림차순으로 정렬해 모두 공개한다.
3. 각 플레이어에게 자기 색 주사위 8개.
4. 중립 주사위(옵션 적용 시): 2명이면 각자 4개, 3~4명이면 각자 2개를 자기 주사위와 별도로 받는다. 3명이면 남는 2개는 매 라운드 시작 시 그 라운드 선 플레이어가 굴려, 각 주사위를 나온 눈의 카지노에 바로 놓는다(선택 없음).
5. 1라운드 선 플레이어는 RNG로 정한다(원작: 가장 나이 많은 사람). 이후 라운드마다 선은 왼쪽(다음 좌석)으로 넘어간다.
## 5. 진행 규칙
- 차례는 선 플레이어부터 좌석 순(시계 방향).
- 내 차례:
1. `ROLL`: 남은 내 주사위와 남은 내 중립 주사위를 모두 함께 굴린다.
2. `PLACE(value)`: 나온 눈 중 하나(`value`)를 고르고, 그 눈이 나온 주사위를 색에 상관없이 "모두" `value`번 카지노에 놓는다. 일부만 놓을 수 없다. 중립 주사위에만 나온 눈을 골라도 된다(그러면 중립 주사위만 놓임).
3. 이미 다른 사람 주사위가 있는 카지노에도 놓을 수 있다.
- 주사위가 하나도 남지 않은 사람은 이후 차례를 건너뛴다(라운드 끝 무렵 한 사람이 연속으로 차례를 가질 수 있음).
- 모든 사람이 주사위를 다 놓으면 라운드 정산:
1. 카지노마다 "주인"별 주사위 수를 센다(주인 = 각 플레이어, 그리고 중립 주사위 전체를 하나의 가상 플레이어 "하우스"로 취급).
2. 동점 제거: 주사위 수가 같은 주인이 2명 이상이면 그 주인들의 주사위를 모두 제거(그 카지노에서 아무것도 못 받음). 하우스도 동점 판정에 포함된다.
3. 남은 주인을 주사위 수 내림차순으로 줄 세우고, 지폐를 금액 내림차순으로 1:1로 준다. 지폐가 모자라면 뒤쪽 사람은 못 받는다.
4. 하우스가 받은 지폐, 그리고 아무도 받지 않고 남은 지폐는 더미 맨 아래에 넣는다(카지노 1→6 순, 각 카지노 안에서는 높은 금액부터).
5. 받은 지폐는 그 플레이어 앞에 놓는다(`hideMoney`면 금액 비공개).
- 정산 후 다음 라운드: 주사위를 모두 돌려받고, 4장 2번 방식으로 카지노에 다시 지폐를 채우고, 선을 다음 사람에게 넘긴다.
- 더미가 바닥나면(사실상 발생하지 않음) 그 카지노는 있는 만큼만 받은 채로 진행한다. 지폐가 0장인 카지노에 주사위를 놓는 것도 허용된다.
### 5.1 정산 예시(원작 규칙서 예시 재구성)
- 카지노 지폐 [8, 3, 1]. 주사위: A 5개, B 3개, C 3개, D 1개 → B·C 동점 제거. A가 8, D가 3을 받고 1은 더미 맨 아래로.
- 카지노 지폐 [4, 4]. A 2개, C 2개, B 1개, D 1개 → A·C 제거, B·D 제거. 아무도 못 받고 두 장 모두 더미 아래로.
- 카지노 지폐 [7, 2]. C 4개, B 2개, D 1개 → C 7, B 2, D 없음.
- 중립 예시(2명): 카지노 지폐 [9]. 하우스 3개, A 2개, B 1개 → 하우스가 9를 가져가 더미 아래로. A·B 모두 0.
## 6. 승패와 점수 계산
- `rounds` 라운드 후 각자 받은 지폐 금액 합계가 점수.
- 동점이면 지폐 장 수가 많은 사람이 이긴다. 그래도 같으면 공동 순위.
- 결과 화면에서 모두의 지폐를 공개한다.
## 7. 지역 룰 / 하우스 룰 (옵션으로 켜고 끄기)
- 중립 주사위 변형(`neutralDice`): 원작 규칙서의 "2~4인 변형". 2명 게임은 중립 주사위 없이는 동점 무효가 거의 일어나지 않아 단조로우므로 기본으로 켠다(`auto`).
- 라운드 수(`rounds`): 짧은 판을 원하면 3.
- 돈 공개(`hideMoney=false`): 어린이 판이나 처음 하는 사람을 위해 금액을 공개.
- 지원하지 않는 변형(문서화만): 확장 "라스베가스 불러바드"의 큰 주사위·7번째 카지노·보너스 카드, "돈이 가장 적은 사람이 이김" 같은 반대 규칙.
## 8. 엔진 설계
### 8.1 상태(State)
```ts
type Owner = PlayerId | 'house';
type Note = number; // 1..9 (만 달러)
interface LasVegasState {
options: LasVegasOptions;
rng: RngState;
seats: PlayerId[];
round: number; // 1..rounds
startSeat: number; // 이번 라운드 선
current: number; // 현재 차례 좌석
phase: 'roll' | 'place' | 'finished';
pile: Note[]; // 비공개 더미(0번 = 맨 위)
casinos: { value: 1|2|3|4|5|6; notes: Note[] /* 내림차순 */; dice: Partial<Record<Owner, number>> }[];
hand: Record<PlayerId, { own: number; neutral: number }>; // 남은 주사위 수
lastRoll: { own: number[]; neutral: number[] } | null; // 현재 차례 굴림 결과
money: Record<PlayerId, Note[]>; // 받은 지폐
roundResults: { round: number; payouts: { casino: number; removedTies: Owner[]; awards: { owner: Owner; note: Note }[]; returned: Note[] }[] }[];
turnSeq: number;
deadlineAt: number | null;
}
```
### 8.2 액션
| type | payload | 누가 / 언제 | 검증 조건 |
|---|---|---|---|
| `ROLL` | 없음 | 현재 차례 사람, `phase='roll'` | 남은 주사위(own+neutral) ≥ 1. 위반: "지금은 굴릴 차례가 아니에요." |
| `PLACE` | `{ value: 1..6 }` | 현재 차례 사람, `phase='place'` | `lastRoll`(own 또는 neutral)에 `value`가 1개 이상. 위반: "그 숫자는 나오지 않았어요." |
| `CONCEDE` | 없음 | 참가자 | 남은 주사위를 버리고(놓지 않음) 이후 차례 제외. 이미 받은 돈은 결과에 유지. 남은 참가자가 1명이면 즉시 종료 |
- `PLACE` 처리 후 다음 차례: 좌석 순으로 남은 주사위가 있는 다음 사람. 아무도 없으면 정산 → 다음 라운드 셋업 또는 종료.
- 3명 + 중립 사용 시 라운드 시작(셋업 직후 포함)에 선 플레이어 이름으로 남는 중립 주사위 2개를 자동 굴려 놓는다(이벤트 `houseDicePlaced`).
- 이벤트: `rolled{player,own,neutral}`, `placed{player,value,ownCount,neutralCount}`, `tiesRemoved{casino,owners}`, `paid{casino,owner,note}`, `notesReturned`, `casinosRefilled`, `roundEnd`, `gameOver`.
### 8.3 공개/비공개 정보 (view)
- 모두에게 공개: 카지노별 지폐(금액)와 주인별 주사위 수, 각자 남은 주사위 수(own/neutral), 현재 굴림 결과, 라운드·선·차례, 정산 내역(누가 몇 번 카지노에서 받았는지).
- 단 `hideMoney=true`이면 정산 내역의 지폐 금액은 받은 본인에게만 보이고, 다른 사람에게는 "1장 받음"으로만 보인다. 하우스가 받은 지폐와 남은 지폐 금액은 공개(카지노에 공개돼 있던 것이므로).
- `hideMoney=true`: 다른 플레이어의 `money`는 장 수만, 본인은 금액 전체. 관전자는 장 수만.
- 참고: 카지노 지폐는 공개 상태에서 분배되므로 주의 깊게 보면 추적이 가능하다(원작도 같음). 이 옵션은 "기억력 요소"를 살리는 장치이며 UI는 기록 보조를 주지 않는다.
- 비공개: `pile` 순서와 장 수 외 내용(남은 장 수만 공개), `rng`.
- 게임 종료 후 결과에서는 모두 공개.
### 8.4 랜덤 요소 (시드 RNG 사용 지점)
- 셋업: 지폐 더미 섞기(Fisher–Yates), 1라운드 선 결정.
- `ROLL`: 자기 주사위 → 중립 주사위 순서로 각각 `1 + floor(rng()*6)`.
- 3명 중립 사용 시 라운드 시작 하우스 주사위 2개 굴림.
- 라운드 간 더미는 다시 섞지 않는다(원작대로 돌려받은 지폐는 맨 아래).
### 8.5 타이머·시간 초과·연결 끊김 시 자동 행동
- `deadline`: `phase` 진입 시 `now + turnSeconds`(굴리기와 놓기 각각).
- `onTimeout`:
- `roll` → `ROLL`.
- `place` → 결정적 선택: 나온 눈 중 (1) 해당 눈 주사위(own+neutral) 수가 가장 많은 것, (2) 동률이면 그 카지노 최고 지폐가 큰 것, (3) 그래도 같으면 작은 숫자.
- 끊긴 사람은 5초 유예 후 자동 행동. 3번 연속 자동이면 "자리 비움" 표시.
### 8.6 종료 조건과 결과(GameResult)
- 마지막 라운드 정산 후 종료.
```ts
interface LasVegasResult {
ranking: { rank: number; player: PlayerId; total: number /* 만 달러 */; notes: Note[] }[];
winners: PlayerId[];
roundTotals: Record<PlayerId, number[]>; // 라운드별 획득액
summary: string; // 예: "지수 승리! 47만 달러 (8장)"
}
```
## 9. UI/UX
- 모바일 세로: 위쪽에 카지노 6곳을 2열 × 3행 카드로(각 카드에 큰 숫자 1~6, 지폐 금액, 색별 주사위 개수 막대), 아래에 내 굴림 결과 영역과 "굴리기" 버튼. PC: 카지노 6곳을 가로 한 줄.
- 조작: 굴린 뒤 같은 눈끼리 자동으로 묶여 "3 × 3개", "5 × 2개(흰 1 포함)"처럼 큰 버튼으로 표시. 버튼을 누르면 해당 카지노가 강조되고 "놓은 뒤 예상 순위"(현재 1등/동점 위험)가 미리 보인 뒤 확정.
- 하이라이트: 놓으면 동점이 되는 카지노는 노란 "동점 주의", 단독 1등이 되면 초록 "1등!".
- 애니메이션: 주사위 굴림, 주사위가 카지노로 날아감, 정산 때 동점 주사위가 "펑" 사라지고 지폐가 승자에게 날아감.
- 초보자 도움말: "같은 숫자는 한꺼번에", "개수가 같으면 둘 다 꽝" 두 문장을 첫 판에 크게 안내.
- 지폐는 실제 화폐와 다른 디자인(알록달록한 놀이용 지폐)으로, "만 달러" 대신 "포인트" 표기 옵션(UI 설정).
## 10. 테스트 체크리스트
- [ ] 셋업: 지폐 54장 구성(6·8·8·6·6·5·5·5·5), 각 카지노 합 ≥ 5, 그리고 마지막 한 장을 빼면 5 미만(필요 이상으로 놓지 않음).
- [ ] `PLACE`는 그 눈의 주사위를 모두 옮긴다(일부만 불가). 나오지 않은 눈 거부.
- [ ] 중립 주사위에만 나온 눈 선택 시 중립 주사위만 놓인다.
- [ ] 정산 예시 4개(5.1)를 그대로 재현해 결과 일치.
- [ ] 하우스와 플레이어 동점 → 둘 다 제거.
- [ ] 하우스가 받은 지폐와 남은 지폐가 정해진 순서로 더미 맨 아래에 들어간다.
- [ ] 주사위가 없는 사람은 차례 건너뜀, 한 사람만 남으면 연속 차례.
- [ ] 라운드마다 선이 다음 좌석으로 이동, 4라운드 후 종료.
- [ ] 3명 + `neutralDice=on`: 라운드 시작 시 하우스 주사위 2개 자동 배치.
- [ ] 5명 + `neutralDice=on` 옵션 검증 거부.
- [ ] 최종 동점: 금액 같으면 장 수 많은 쪽 승, 그것도 같으면 공동 우승.
- [ ] 시간 초과: 굴리기 자동, 놓기는 개수 최다 눈 선택.
- [ ] 연결 끊김 사용자가 있어도 라운드가 끝까지 진행.
- [ ] 정보 유출: `hideMoney=true`에서 다른 플레이어·관전자 View에 금액이 없음(장 수만). View에 `pile` 내용·`rng` 없음.
- [ ] 리플레이 결정성: 같은 시드·액션 열 → 같은 최종 금액.
## 11. 참고 자료
- 원작 규칙서(영문, Ravensburger/alea, Rüdiger Dorn): https://cdn.1j1ju.com/medias/d1/8e/c6-las-vegas-rulebook.pdf (구성물·지폐 분포·동점 제거·2~4인 중립 주사위 변형·동점 시 지폐 장 수)
- Yucata 규칙(중립 주사위 세부: 중립만 나온 눈 선택 가능, 하우스 획득 지폐는 더미 아래): https://www.yucata.de/en/Rules/LasVegas
- Wikipedia "Las Vegas (board game)": https://en.wikipedia.org/wiki/Las_Vegas_(board_game)
- 나무위키 "라스베가스(보드게임)": https://namu.wiki/w/라스베가스(보드게임)
- BoardGameGeek "Las Vegas": https://boardgamegeek.com/boardgame/117959/las-vegas
## 12. 메모 (상표·법적 주의 등)
- "Las Vegas"는 게임 제목으로 상표 등록돼 있을 수 있고(alea/Ravensburger), 원작 카지노 이름(실제 카지노 상호)은 상표다. 화면 표시 이름 후보: "주사위 카지노", "럭키 6", "주사위 놀이공원"(카지노 대신 놀이기구 6곳으로 테마 변경 시). 규칙 자체는 저작권 보호 대상이 아니다.
- 사행성 주의: 돈은 방 안에서만 쓰는 가상 지폐이며 저장·이월·교환이 없다. 실제 돈·상품을 걸 수 없음을 규칙 보기에 명시한다. 아이들 대상이면 카지노 테마 대신 놀이공원·시장 테마 스킨을 권장한다(게임물관리위원회 등급 분류에서 "사행성 모사" 요소로 볼 여지를 줄임).