- 개요, 조사(BGA·한국 인기 보드게임·UI/UX), 아키텍처, 실시간 프로토콜, 안정성·보안, 계정, 로비·방, UI/UX, 데이터 모델, 게임 엔진, 테스트, 배포·운영, 로드맵(M0~M9), 사용자 결정 항목 - 게임별 규칙·엔진 설계·UI·테스트 체크리스트 26종 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
268 lines
19 KiB
Markdown
268 lines
19 KiB
Markdown
# 구십구 (`ninety-nine`)
|
||
|
||
> 마일스톤: M7 · 인원: 최소 2 ~ 최대 10명 · 예상 시간: 약 5~15분 · 난이도: 쉬움
|
||
|
||
## 1. 개요
|
||
- 차례대로 카드를 1장씩 내며 숫자를 더해 간다. 합계를 99보다 크게 만들 수밖에 없는 사람이 탈락(또는 목숨 1개를 잃음)하는 서바이벌 카드 게임이다.
|
||
- 이 문서는 두 가지 규칙을 담는다.
|
||
- `kr-product` 모드(기본): 코리아보드게임즈의 카드게임 "구십구"(2~10명, 만 8세 이상, 약 5분) 방식. 전용 카드(1~8, 10, ±9, ±10, 0, 조커)를 쓴다.
|
||
- `classic` 모드: 트럼프 52장으로 하는 전통 게임 "99(Ninety-Nine)". 영미권 놀이 게임이고, 나무위키 "99(플레잉 카드)"에도 같은 계열 규칙이 있다.
|
||
- 인원 근거
|
||
- 코리아보드게임즈 공식 상품 페이지에 2~10명으로 나온다(일부 쇼핑몰은 2~6명으로 표기).
|
||
- 나무위키 "99(플레잉 카드)"도 2~10명이다.
|
||
- 그래서 2~10명으로 한다.
|
||
|
||
### 확인된 것과 확인되지 않은 것 (오너 확인 필요)
|
||
- 확인됨(코리아보드게임즈 매거진 기사, 공식 상품 페이지)
|
||
- 1~8 카드 각 7장, 10 카드 21장.
|
||
- 특수 카드 ±9, ±10, 0, 조커(정확히 2장).
|
||
- 자기 차례에 1장을 내고 이전 수에 더한 새 수를 말한다.
|
||
- 99를 넘게 만드는 카드는 낼 수 없고, 낼 카드가 1장도 없으면 탈락한다. 혼자 남으면 승리한다.
|
||
- ±9·±10은 더하거나 뺄 수 있다. 0은 수 변화 없이 진행 방향을 바꾼다. 조커는 앞 수와 상관없이 60~99 중 원하는 수를 부른다.
|
||
- 확인되지 않음(공식 규칙서 원문을 구하지 못함. 아래는 이 문서의 기본값이고 모두 옵션)
|
||
- ±9, ±10, 0 카드의 장수. 기본값은 각 4장(추정)이다.
|
||
- 시작 손패 장수. 기본값은 3장(전통 99와 같음)이다.
|
||
- 카드를 낸 뒤 1장 보충 여부. 기본값은 보충한다(전통 99와 같음).
|
||
- 빼기로 0 미만이 될 때 처리. 기본값은 0 미만이 되는 빼기는 금지다.
|
||
- 탈락자가 생긴 뒤 합계를 이어 갈지 초기화할지. 기본값은 이어 간다.
|
||
- 칩(목숨) 변형이 공식 규칙서에 있는지. 일부 소개 글에 "칩 3개, 99를 넘기면 1개 잃음" 변형이 언급되지만 원문으로 확인하지 못했다. 전통 99의 토큰 3개 규칙과 같은 구조라 `lives` 옵션으로 둔다.
|
||
|
||
## 2. 모드와 옵션
|
||
| 옵션 키 | 설명 | 선택지 | 기본값 |
|
||
|---|---|---|---|
|
||
| `mode` | 규칙 | `kr-product` / `classic` | `kr-product` |
|
||
| `handSize` | 손패 장수 | 3 / 4 / 5 | 3 |
|
||
| `refill` | 카드를 낸 뒤 1장 보충 | on / off | on |
|
||
| `lives` | 목숨(토큰) 수. 0이면 목숨 없이 바로 탈락 | 0 / 1 / 2 / 3 / 5 | `kr-product` 0, `classic` 3 |
|
||
| `onTheBoard` | 목숨을 다 잃은 뒤에도 한 번 더 질 때까지 남음(전통 변형) | on / off | off |
|
||
| `afterElimination` | (`lives=0`) 탈락 뒤 합계 처리 | `continue`(그대로 이어 감) / `reset`(0으로, 다시 나눔) | `continue` |
|
||
| `floorAtZero` | 빼기 결과가 0 미만일 때 | `forbid`(그런 빼기는 못 냄) / `clamp`(0으로 맞춤) | `forbid` |
|
||
| `specialCounts` | (`kr-product`) ±9, ±10, 0 각 장수 | 2 / 3 / 4 / 5 / 6 | 4 |
|
||
| `jokerRange` | (`kr-product`) 조커로 부를 수 있는 범위 | `60-99`(원작) / `0-99` | `60-99` |
|
||
| `aceHigh` | (`classic`) A의 큰 값 | 10(나무위키) / 11(Bicycle) | 11 |
|
||
| `deckCount` | (`classic`) 덱 수 | `auto`(7인 이상 2벌) / 1 / 2 | `auto` |
|
||
| `turnSeconds` | 턴 제한 시간 | 10 / 15 / 20 / 30 | 15 |
|
||
|
||
## 3. 구성물
|
||
`kr-product` (기본값 기준 91장)
|
||
|
||
| 카드 | 효과 | 장수 |
|
||
|---|---|---|
|
||
| 1~8 | 그 숫자만큼 더함 | 각 7장(56장) |
|
||
| 10 | 10 더함 | 21장 |
|
||
| ±9 | 9를 더하거나 뺌(낸 사람이 선택) | `specialCounts`(기본 4, 추정) |
|
||
| ±10 | 10을 더하거나 뺌 | `specialCounts`(기본 4, 추정) |
|
||
| 0 | 수 변화 없음, 진행 방향 반대 | `specialCounts`(기본 4, 추정) |
|
||
| 조커 | 앞 수와 상관없이 60~99 중 원하는 수로 만듦 | 2장 |
|
||
|
||
- 9 숫자 카드는 없다(±9만 있음).
|
||
- 목숨을 쓰면(`lives > 0`) 플레이어마다 목숨 토큰을 그만큼 준다. 방 안에서만 쓰는 표시용이다.
|
||
|
||
`classic` (트럼프 52장, Bicycle 규칙 기준)
|
||
|
||
| 카드 | 효과 |
|
||
|---|---|
|
||
| A | 1 또는 `aceHigh`(11) 더함(낸 사람이 선택) |
|
||
| 2, 3, 5, 6, 7, 8 | 그 숫자만큼 더함 |
|
||
| 4 | 0(수 변화 없음), 진행 방향 반대 |
|
||
| 9 | 0(수 변화 없음), 그냥 넘김 |
|
||
| 10 | 10을 뺌 |
|
||
| J, Q | 10 더함 |
|
||
| K | 합계를 바로 99로 만듦(이미 99면 그대로 99) |
|
||
|
||
- 조커는 쓰지 않는다. `deckCount = 2`이면 104장이다.
|
||
|
||
## 4. 준비(셋업)
|
||
1. 모드에 맞는 덱을 만들고 시드 RNG로 섞는다.
|
||
2. 선 플레이어를 RNG로 정한다. 진행은 시계 방향이다.
|
||
3. 각자 `handSize`장을 받는다. 남은 카드는 뽑을 더미가 된다.
|
||
4. 합계는 0에서 시작한다.
|
||
5. 목숨을 쓰면 각자 `lives`개를 받는다.
|
||
|
||
## 5. 진행 규칙
|
||
|
||
### 5.1 턴
|
||
1. **탈락 판정(턴 시작 때 서버 자동)**: 현재 플레이어가 낼 수 있는 카드가 하나도 없으면 바로 "패배 처리"(5.3)를 한다. 패배 처리 결과 탈락하지 않은 경우(목숨이 남음)에는 새 라운드가 시작된다.
|
||
2. **카드 내기**: 낼 수 있는 카드 1장을 낸다. ±카드는 더하기/빼기를, A는 1/11을, 조커는 숫자를 함께 고른다. 새 합계가 공개된다.
|
||
3. **보충**(`refill = on`): 뽑을 더미에서 1장을 가져온다. 더미가 비었으면 버린 카드를 모두 섞어 새 더미를 만든다(합계는 그대로). 그래도 없으면 보충하지 않는다.
|
||
4. 다음 차례로 넘긴다. 0(또는 `classic`의 4)이면 방향을 반대로 바꾼 뒤 넘긴다.
|
||
|
||
- 패스는 없다. 낼 수 있는 카드가 있으면 반드시 1장을 내야 한다.
|
||
- 2인일 때 방향 반대 카드는 방향만 바뀌고 다음 차례는 여전히 상대다.
|
||
|
||
### 5.2 낼 수 있는 카드(합법 조건)
|
||
합계를 S, 카드를 낸 뒤 합계를 S'라 할 때 S' ≤ 99여야 한다.
|
||
|
||
`kr-product`
|
||
- 1~8, 10: S' = S + 값.
|
||
- ±9, ±10
|
||
- 더하기면 S' = S + 값.
|
||
- 빼기면 S' = S - 값. `floorAtZero = forbid`이면 S' ≥ 0이어야 하고, `clamp`이면 S' = max(0, S - 값).
|
||
- 두 방향 중 하나라도 합법이면 낼 수 있다.
|
||
- 0: S' = S. 항상 낼 수 있다.
|
||
- 조커: S'를 `jokerRange`(60~99) 안의 아무 정수로 고른다. 항상 낼 수 있다. 현재 합계와 같은 수를 골라도 된다.
|
||
|
||
`classic`
|
||
- A: 1 또는 11 중 S' ≤ 99인 값.
|
||
- 2, 3, 5~8, J, Q: S' = S + 값.
|
||
- 4, 9: S' = S. 항상 낼 수 있다.
|
||
- 10: S' = S - 10. `forbid`이면 S ≥ 10일 때만, `clamp`이면 항상 가능.
|
||
- K: S' = 99. 항상 낼 수 있다.
|
||
|
||
### 5.3 패배 처리
|
||
- `lives = 0`(`kr-product` 기본)
|
||
- 그 플레이어는 탈락한다. 손패는 버린 더미로 간다.
|
||
- `afterElimination = continue`면 같은 합계로 다음 사람 차례가 된다(다음 사람도 낼 카드가 없으면 연달아 탈락할 수 있다).
|
||
- `reset`이면 합계를 0으로 하고 남은 사람 손패를 모두 거둬 다시 섞어 나눈다. 탈락자의 다음 사람이 시작한다.
|
||
- `lives > 0`
|
||
- 그 플레이어가 목숨 1개를 잃는다. 이번 라운드는 끝난다.
|
||
- 목숨이 0이 되면 탈락한다. `onTheBoard = on`이면 목숨 0인 상태로 계속 하고, 그 상태에서 한 번 더 지면 탈락한다.
|
||
- 새 라운드: 모든 카드를 거둬 섞고, 남은 사람에게 다시 나누고, 합계 0에서 시작한다. 진 사람이 탈락하지 않았으면 진 사람이 먼저 하고, 탈락했으면 그 다음 사람이 먼저 한다.
|
||
- 남은 사람이 1명이면 게임이 끝난다.
|
||
|
||
### 5.4 예시 (`kr-product`, 3인)
|
||
- 합계 85에서 A가 10을 내 95가 된다. A가 보충한다.
|
||
- B의 손패는 [8, 7, ±9]이다. 8과 7은 99를 넘는다. ±9를 빼기로 내서 86이 된다.
|
||
- C의 손패는 [10, 10, 0]이다. 0을 내서 86 그대로이고 방향이 반대가 되어 B 차례가 된다.
|
||
- B의 손패는 [8, 7, 6](보충한 6)이다. 8 → 94, 7 → 93, 6 → 92 모두 가능하다. B가 7을 내서 93.
|
||
- 방향이 바뀌었으므로 다음은 A다. A의 손패가 [8, 10, 7]이면 101, 103, 100이라 낼 카드가 없다. A는 턴 시작 때 탈락하고 C 차례가 된다.
|
||
|
||
## 6. 승패와 점수 계산
|
||
- 마지막까지 남은 1명이 승자다.
|
||
- 순위: 늦게 탈락한 사람이 앞선다. 같은 시점 동시 탈락은 없다(턴 순서대로 판정).
|
||
- 목숨을 쓰는 경우에도 탈락 순서로 순위를 정한다. 결과 화면에 각자 잃은 목숨 수를 보여 준다.
|
||
- 점수, 칩, 돈은 없다. 목숨 토큰은 이 판에서만 쓰는 표시이고 방 밖으로 이어지지 않는다.
|
||
|
||
## 7. 지역 룰 / 하우스 룰 (옵션으로 켜고 끄기)
|
||
- 목숨(칩) 변형(`lives`, `onTheBoard`): 전통 99의 토큰 3개 규칙이다. 구십구 소개 글 일부에서도 "칩 3개" 변형이 언급된다(원문 미확인).
|
||
- 손패 장수(`handSize`), 보충 여부(`refill`).
|
||
- 탈락 뒤 합계 처리(`afterElimination`).
|
||
- 0 미만 빼기 처리(`floorAtZero`).
|
||
- 조커 범위 확장(`jokerRange`, 어린이용 0~99).
|
||
- `classic`의 A 큰 값(`aceHigh` 10/11).
|
||
- 지원하지 않는 변형(문서화만)
|
||
- Wikipedia "표준" 변형: 3이 다음 사람 건너뛰기, 9가 99로 만들기, 10이 ±10, K가 0.
|
||
- 정확히 99를 만들면 보너스, 같은 숫자 연속 내기 금지 같은 지역 규칙.
|
||
- 필요하면 `classic` 카드 효과표를 옵션 프리셋으로 늘린다.
|
||
|
||
## 8. 엔진 설계
|
||
### 8.1 상태(State)
|
||
```ts
|
||
type NNCard =
|
||
| { id: string; kind: 'add'; v: number } // kr: 1..8, 10 / classic: 2,3,5,6,7,8, J/Q(10)
|
||
| { id: string; kind: 'plusMinus'; v: 9 | 10 } // kr ±9, ±10
|
||
| { id: string; kind: 'reverse' } // kr 0 / classic 4
|
||
| { id: string; kind: 'hold' } // classic 9
|
||
| { id: string; kind: 'minus'; v: 10 } // classic 10
|
||
| { id: string; kind: 'ace' } // classic A (1 또는 aceHigh)
|
||
| { id: string; kind: 'to99' } // classic K
|
||
| { id: string; kind: 'joker' }; // kr 조커 (jokerRange)
|
||
// 화면 표시용으로 원래 표기(rank/suit 또는 kr 라벨)를 별도 필드 face로 둔다.
|
||
|
||
interface NinetyNineState {
|
||
mode: 'kr-product' | 'classic';
|
||
options: NNOptions;
|
||
rng: RngState;
|
||
seats: PlayerId[];
|
||
hands: Record<PlayerId, NNCard[]>; // 비공개
|
||
drawPile: NNCard[]; // 비공개
|
||
discard: NNCard[]; // 공개(최근 몇 장만 view)
|
||
total: number; // 공개 합계
|
||
direction: 1 | -1;
|
||
current: PlayerId;
|
||
alive: Record<PlayerId, boolean>;
|
||
lives: Record<PlayerId, number>; // lives=0 모드에서는 사용 안 함
|
||
onBoard: Record<PlayerId, boolean>; // onTheBoard 상태
|
||
eliminationOrder: PlayerId[];
|
||
round: number;
|
||
phase: 'playing' | 'finished';
|
||
turnStartedAt: number;
|
||
seq: number;
|
||
}
|
||
```
|
||
|
||
### 8.2 액션
|
||
| type | payload | 누가 / 언제 | 검증 조건 |
|
||
|---|---|---|---|
|
||
| `play` | `{ cardId: string; sign?: '+' \| '-'; aceValue?: 1 \| 10 \| 11; jokerValue?: number }` | `current`, playing | 카드가 손에 있음. ±카드는 `sign` 필수, A는 `aceValue` 필수(1 또는 `aceHigh`), 조커는 `jokerValue` 필수이고 `jokerRange` 안의 정수. 5.2 조건으로 계산한 S' ≤ 99(그리고 `forbid`면 S' ≥ 0) |
|
||
|
||
- 플레이어가 보내는 액션은 `play` 하나뿐이다. 탈락, 목숨 감소, 라운드 재시작, 보충은 `apply` 안에서 자동으로 처리한다.
|
||
- `play`를 적용한 직후 다음 플레이어를 정한다. 그 플레이어에게 합법 수가 없으면 같은 `apply` 안에서 패배 처리를 하고, 다시 다음 사람을 검사한다(반복). 이 과정을 이벤트로 순서대로 남긴다.
|
||
- 이렇게 하면 "낼 카드가 없는 사람이 타이머를 기다리는" 상황이 없다.
|
||
- 이벤트 예: `cardPlayed{player, face, total}`, `directionChanged`, `cardDrawn{player}`, `reshuffled`, `lifeLost{player, left}`, `eliminated{player}`, `roundStarted{round, starter}`.
|
||
- `reason` 예: "99를 넘어서 낼 수 없어요", "0보다 작아져서 뺄 수 없어요", "더하기와 빼기 중 하나를 골라 주세요", "조커는 60부터 99 사이 숫자만 고를 수 있어요".
|
||
|
||
### 8.3 공개/비공개 정보 (view)
|
||
- 모두(관전자 포함): 현재 합계, 방향, 현재 차례, 각자 손패 장수, 목숨, 생존 여부, 탈락 순서, 뽑을 더미 장수, 최근에 낸 카드 몇 장과 그때의 합계 기록.
|
||
- 본인만
|
||
- 자기 손패.
|
||
- 각 카드의 합법 여부와 결과 미리보기(예: "±9 → 더하면 104 불가 / 빼면 86").
|
||
- 탈락 때 손패는 공개하지 않고 장수만 버린 더미로 옮긴다(실물에서는 보일 수 있지만 다른 사람 추리에 영향이 없도록 비공개로 둔다).
|
||
- 절대 보내지 않는 것: 남의 손패, 더미 순서, RNG 상태. 보충 이벤트는 본인에게만 카드 내용을 준다.
|
||
|
||
### 8.4 랜덤 요소 (시드 RNG 사용 지점)
|
||
- `setup`: 덱 섞기, 선 플레이어.
|
||
- 더미 소진 때 버린 카드 다시 섞기.
|
||
- 라운드 재시작(목숨 모드, `reset`) 때 다시 섞기.
|
||
|
||
### 8.5 타이머·시간 초과·연결 끊김 시 자동 행동
|
||
- `deadline = turnStartedAt + turnSeconds*1000`.
|
||
- `onTimeout(state, p)`: 합법인 (카드, 선택값) 조합 중 결과 합계 S'가 가장 작은 것을 고른다.
|
||
- 같으면 우선순위: 0/4/9(변화 없음) → 일반 숫자 카드 → ±카드 → K/조커. 그래도 같으면 카드 ID 순.
|
||
- 조커는 `jokerRange` 최소값(60)으로 낸다.
|
||
- 이 규칙은 본인 손패와 공개 합계만 쓰므로 정보 유출이 없고 결정적이다.
|
||
- 합법 수가 없는 경우는 타이머까지 가지 않고 `apply`에서 이미 처리된다(8.2).
|
||
- 연결이 끊겨도 위 자동 행동으로 계속 진행한다. 연속 3턴 타임아웃이면 서버가 마감을 3초로 줄인다.
|
||
|
||
### 8.6 종료 조건과 결과(GameResult)
|
||
- 생존자가 1명이 되면 `finished`.
|
||
```ts
|
||
interface GameResult {
|
||
ranking: { player: PlayerId; rank: number; livesLost: number; eliminatedAtRound: number | null }[];
|
||
winner: PlayerId[];
|
||
summary: string; // "끝까지 살아남은 사람은 지호 님! 마지막 합계 97"
|
||
}
|
||
```
|
||
|
||
## 9. UI/UX
|
||
- 모바일 세로 화면
|
||
- 가운데: 현재 합계를 아주 크게(예: 72pt) 보여 준다. 99에 가까울수록 색이 초록 → 노랑 → 빨강으로 바뀌는 게이지 링을 두른다.
|
||
- 위: 상대 아바타(손패 장수, 목숨 하트, 차례 표시), 진행 방향 화살표.
|
||
- 아래: 내 손패 3장을 큰 카드로 보여 준다(최소 72×100px).
|
||
- 조작
|
||
- 카드를 탭하면 "내면 → 81"처럼 결과 합계 미리보기가 카드 위에 뜬다. 한 번 더 탭하면 낸다.
|
||
- ±카드를 탭하면 [+9 → 95] [−9 → 77] 두 버튼이 뜬다. 불가능한 쪽은 비활성이다.
|
||
- 조커를 탭하면 60~99 숫자 다이얼(+/− 버튼과 빠른 선택 60/90/99)이 뜬다.
|
||
- 낼 수 없는 카드는 흐리게 하고 "99 초과" 배지를 붙인다.
|
||
- 애니메이션: 합계 숫자가 올라가는 카운트 애니메이션, 방향 전환 화살표 회전, 탈락 때 아바타 흑백 처리, 목숨 하트가 깨지는 연출.
|
||
- 초보 도움말: "99를 넘기면 안 돼요!" 한 줄 규칙과 특수 카드 표. 어린이 방 추천 설정(조커 0~99, 손패 4장).
|
||
- 실시간 감각: 턴이 빨라서 타이머 링을 크게 보여 주고, 내 차례가 되면 진동(모바일 지원 시)으로 알린다.
|
||
|
||
## 10. 테스트 체크리스트
|
||
- [ ] 덱 구성: `kr-product` 기본값 91장(1~8 각 7, 10이 21, ±9/±10/0 각 4, 조커 2). `specialCounts=2`면 85장. `classic` 52장, 7인 이상 `auto`면 104장.
|
||
- [ ] 같은 시드면 같은 분배, 같은 선이 나온다.
|
||
- [ ] 합계 95에서 손패 [8, 5, 4] (`kr-product`)이면 4만 합법이다. 4를 내서 99가 된다. 다음 사람이 [1, 2, 3]만 있으면 턴 시작 때 바로 탈락한다.
|
||
- [ ] ±10: 합계 5에서 빼기는 `forbid`면 거부된다. `clamp`면 0이 된다. 더하기는 15로 허용된다.
|
||
- [ ] 조커: 합계 20에서 조커로 99를 고르면 99가 된다. 59는 거부되고(`60-99`), 100도 거부된다.
|
||
- [ ] 0 카드: 3인에서 A → B 차례에 B가 0을 내면 방향이 반대가 되어 다음이 A다. 2인에서는 상대 차례 그대로다.
|
||
- [ ] `classic`: 합계 90에서 K → 99, 그다음 사람은 4/9/10/K만 낼 수 있다. A는 1이어도 100이라 거부된다. 합계 88에서 A를 11로 내면 99로 허용된다.
|
||
- [ ] `lives=3`: 진 사람이 목숨 1개를 잃고, 합계 0으로 새 라운드가 시작되며 진 사람이 먼저 한다. 목숨 0이면 탈락하고 다음 사람이 시작한다. `onTheBoard`면 0개에서 한 번 더 져야 탈락한다.
|
||
- [ ] 연쇄 탈락(`lives=0`, `continue`): 합계 98에서 다음 두 사람 모두 낼 카드가 없으면 한 번의 `apply` 안에서 두 명이 순서대로 탈락하고, 세 번째 사람 차례가 된다. 이벤트 순서가 맞다.
|
||
- [ ] 더미 소진: 보충할 때 더미가 비면 버린 카드가 섞여 보충되고 합계는 그대로다.
|
||
- [ ] 시간 초과: 손패 [10, 3, 0], 합계 50이면 자동 행동은 0(결과 50, 가장 작음)을 낸다. 손패 [±9, 3, 0], 합계 50이면 −9(결과 41)를 낸다.
|
||
- [ ] 연결 끊김: 끊긴 플레이어 차례가 자동으로 진행되고 게임이 멈추지 않는다.
|
||
- [ ] 정보 유출: 관전자와 상대 view에 남의 손패, 보충 카드 내용, 더미 순서가 없다. 탈락자 손패도 공개되지 않는다.
|
||
- [ ] 차례가 아닌 `play`, `sign` 없는 ±카드, 범위 밖 `jokerValue`, 중복 패킷이 거부되고 상태가 바뀌지 않는다.
|
||
|
||
## 11. 참고 자료
|
||
- 코리아보드게임즈 매거진 "숫자를 더해나가며 한계에 도전하라!": https://www.koreaboardgames.com/magazine/menuDetail?boardCd=contents&postNo=947 (1~8 각 7장, 10이 21장, ±9·±10·0·조커 효과, 조커 2장 60~99, 99 초과 금지, 낼 카드 없으면 탈락)
|
||
- 코리아보드게임즈 상품 페이지 "구십구": https://www.koreaboardgames.com/product/detail?prdCd=PD2024002211B1JR (2~10명, 만 8세+, 5분)
|
||
- 나무위키 "99(플레잉 카드)": https://namu.wiki/w/99(플레잉%20카드) (트럼프판 2~10명, 손패 3장, 내고 1장 보충, A 1/10, 4 반대, 9는 0, 10은 −10, J·Q 10, K는 99)
|
||
- Bicycle Cards "99 (Ninety Nine)": https://bicyclecards.com/how-to-play/99-ninety-nine (토큰 3개, 손패 3장, A 1/11, 4 반대, 9 패스, 10 −10, K 99, 넘기면 토큰 1개 잃고 라운드 종료)
|
||
- Wikipedia "Ninety-nine (addition card game)": https://en.wikipedia.org/wiki/Ninety-nine_(addition_card_game) (토큰 3개, 지역 변형 목록)
|
||
|
||
## 12. 메모 (상표·법적 주의 등)
|
||
- "구십구"는 코리아보드게임즈가 파는 상품명이다. 숫자 이름이라 상표 효력이 약할 수 있지만 안전하게 표시 이름을 바꾸는 것을 권한다. 후보: "99 넘기지 마!", "아흔아홉", "숫자 더하기 99"(사용자 선택).
|
||
- 전통 게임 "99(Ninety-Nine)" 규칙 자체는 공공 영역이다. `kr-product` 모드의 전용 카드 구성(±9, ±10, 0, 조커 60~99)은 상품의 고유 설계를 따른 것이다. 규칙 자체는 저작권 보호 대상이 아니지만, 카드 그림과 규칙서 문장은 쓰지 않고 직접 만든다.
|
||
- 목숨(칩) 토큰은 방 안에서만 쓰는 게임 내 표시다. 돈, 포인트, 교환과 연결하지 않는다. 화면 용어는 도박 느낌을 피하려고 "칩" 대신 "목숨"(하트)을 쓴다.
|