# 바둑 (`baduk`) > 마일스톤: M2 · 인원: 최소 2 ~ 최대 2명 · 예상 시간: 9줄 약 10~20분, 13줄 약 30분, 19줄 약 60~120분 · 난이도: 어려움 ## 1. 개요 - 흑과 백이 번갈아 교차점에 돌을 놓아 더 많은 집(영역)을 차지하는 2인 전략 게임. 한국에서 어린이 교육(바둑 학원)부터 어르신 여가까지 폭넓게 즐기며, 한국기원 규칙(일본식과 같은 계가 방식, 덤 6집 반)이 국내 표준이다. - 인원 근거: 원작이 흑·백 2인 게임. 최소 2, 최대 2. 그 외는 관전자. - 완전 정보 게임. 숨길 정보는 없고 서버 내부 값(RNG 상태)만 view에서 제외한다. ## 2. 모드와 옵션 | 옵션 키 | 설명 | 선택지 | 기본값 | |---|---|---|---| | `boardSize` | 판 크기 | `9` / `13` / `19` | `19` (방 만들기 화면에서 초보에게 9줄 추천 문구) | | `scoring` | 계가 방식 | `territory`(한국·일본식 집 계산) / `area`(중국식 영역 계산) | `territory` | | `komi` | 덤 (백에게 더하는 점수, 0.5 단위, -10 ~ 10) | 숫자 | 맞바둑: `territory` 6.5, `area` 7.5 / 접바둑: 0.5 | | `handicap` | 접바둑 치석 수 (흑이 미리 놓는 돌) | 0, 2~9 (9줄은 0, 2~5) | 0 | | `koRule` | 패 규칙 | `positionalSuperko`(동형 반복 금지) / `korean`(단순 패 + 삼패 등 장생형 반복 시 무승부) | `positionalSuperko` | | `colorAssignment` | 흑백 결정 | `nigiri`(무작위) / `hostBlack` / `hostWhite` | `nigiri` (접바둑이면 방장이 하수/상수 지정) | | `timeControl.kind` | 시간 방식 | `none` / `byoyomi`(기본 시간 + 초읽기) / `fischer` | `byoyomi` | | `timeControl.mainSec` | 기본 시간 | 0 ~ 3600 | 9줄 180, 13줄 600, 19줄 1200 | | `timeControl.periodSec` | 초읽기 1회 시간 | 10 / 20 / 30 / 60 | 30 | | `timeControl.periods` | 초읽기 횟수 | 1 ~ 5 | 3 | | `timeControl.incSec` | `fischer` 수당 추가 | 0 ~ 30 | 10 | | `idleLimitSec` | `none`일 때 무응답 한도 | 300 / 600 | 600 | | `undo` | 무르기 허용 횟수(1인당, 상대 동의) | `off` / `1` / `3` / `unlimited` | `3` | | `drawOffer` | 무승부(빅) 합의 제안 허용 | `true` / `false` | `true` | | `atariWarning` | 단수 경고 힌트(내 돌이 단수에 몰리면 표시) | `true` / `false` | `true` | | `scoringDeadlineSec` | 사석 확인 단계 제한 시간 | 120 / 180 / 300 | 180 | | `disconnectGraceSec` | 연결 끊김 유예 | 60 / 120 / 300 | 120 | ## 3. 구성물 - 판: 9×9, 13×13, 19×19 교차점. 화점(별 표시): 9줄 C3·G3·C7·G7·E5, 13줄 D4·K4·D10·K10·G7, 19줄 D4·K4·Q4·D10·K10·Q10·D16·K16·Q16. - 좌표 표기: 열은 A부터, `I`를 건너뛴다(A B C D E F G H J K …). 행은 아래에서 위로 1부터. 내부 좌표 `(x, y)`: `x` 왼→오 0부터, `y` 위→아래 0부터. - 흑돌·백돌: 개수 제한 없음. 따낸 돌(사석/포로) 수를 각자 센다. ## 4. 준비(셋업) 1. 흑백 결정: `nigiri`면 시드 RNG로 무작위. 접바둑이면 하수가 흑. 2. 맞바둑: 빈 판, 흑이 먼저 둔다. 3. 접바둑(`handicap = N`): 흑이 아래 고정 위치에 N개를 놓고(엔진이 자동 배치), 백이 먼저 둔다. 위치(흑 기준, 한국·일본 관례): | N | 19줄 | 13줄 | 9줄 | |---|---|---|---| | 2 | Q16, D4 | K10, D4 | G7, C3 | | 3 | + Q4 | + K4 | + G3 | | 4 | + D16 | + D10 | + C7 | | 5 | 4점 + K10 | 4점 + G7 | 4점 + E5 | | 6 | 4점 + D10, Q10 | 4점 + D7, K7 | — | | 7 | 6점 + K10 | 6점 + G7 | — | | 8 | 4점 + D10, Q10, K4, K16 | 4점 + D7, K7, G4, G10 | — | | 9 | 8점 + K10 | 8점 + G7 | — | (참고: GTP 프로토콜은 3점의 세 번째 돌을 D16에 두는 등 관례가 다르다. 본 서비스는 위 표를 고정 사용한다.) 4. 덤: 맞바둑 기본 6.5(`area`는 7.5). 접바둑은 0.5(무승부 방지). `area` 접바둑은 추가로 백에게 N점 보정(중국 규칙의 치석 보정, 9.2절 참고). 5. 시계 초기화, 포로 0, `positionHistory`에 초기 국면 해시 추가. ## 5. 진행 규칙 ### 5.1 턴 - 차례인 플레이어는 착수 또는 패스 중 하나를 한다. - 용어: 연결(chain) = 상하좌우로 이어진 같은 색 돌 묶음. 활로(liberty) = 연결에 상하좌우로 맞닿은 빈 교차점. ### 5.2 착수 처리 순서 (서버) 1. 빈 교차점인지 확인. 2. 돌을 놓는다. 3. 놓은 돌에 맞닿은 상대 연결 중 활로가 0인 것을 모두 판에서 들어내고 내 포로에 더한다. 4. 놓은 돌이 속한 내 연결의 활로가 0이면 자충수(자살수) → 불법. 원상복구하고 거부. 5. 패 규칙 검사 (5.3). 위반이면 원상복구하고 거부. 6. 확정: 기보 기록, 국면 해시를 `positionHistory`에 추가, 연속 패스 카운트 0, 차례 넘김. ### 5.3 패(ko) 규칙 — 선택과 근거 - 기본값 `positionalSuperko`(동형 반복 금지): 착수 결과의 판 전체 배치(차례와 무관, 돌 색 배치만)가 이 대국에서 이전에 한 번이라도 나왔던 배치와 같으면 그 착수는 불법. 단순 패(바로 되따기 금지)는 이 규칙에 자동 포함된다. - 근거 1: 한국기원 규칙의 삼패·사패·장생 처리("어느 쪽도 양보하지 않으면 무승부/무효")는 심판 판단이 필요한데, 온라인에서는 판정할 심판이 없고 어린이·어르신에게 "판 무효"는 납득하기 어렵다. - 근거 2: 동형 반복 금지는 중국·AGA·뉴질랜드·Tromp-Taylor 규칙에서 쓰는 검증된 방식이고, 해시 집합 조회만으로 결정적으로 판정 가능하다. 무한 반복이 원천 봉쇄되어 서버 안정성에도 유리하다. - 근거 3: 실전에서 단순 패 이외의 동형 반복은 극히 드물어, 한국식과 결과가 달라지는 경우가 거의 없다. - 패스는 판을 바꾸지 않으므로 슈퍼코 검사 대상이 아니다(항상 합법). - 옵션 `korean`: 단순 패만 금지(직전 상대 착수로 돌 1개를 따냈고 그 돌이 1점 단독 연결이며, 내가 그 자리에 두어 정확히 그 돌 하나를 되따는 경우 금지). 판 전체 배치 + 둘 차례가 같은 국면이 세 번째로 나타나면 즉시 무승부(`reason: 'repetition'`)로 종료(삼패·순환패·장생에 해당). - 해시: 길이 `size*size` 문자열(`.`, `b`, `w`) 그대로를 Set에 저장하거나, 고정 상수 테이블의 Zobrist 64비트 해시(게임 RNG와 무관한 상수)를 쓴다. 19줄 300수 기준 문자열 방식도 약 110KB로 충분히 작다. ### 5.4 패스와 종국 - 패스는 언제나 합법. 패스가 연속 2번(흑·백 각 1번) 나오면 대국 정지 → 사석 확인 단계(`scoring`)로 전환. - `korean`·`territory`에서 패스로 상대에게 포로를 주지 않는다(일본식처럼 패스는 무료). `area`도 마찬가지. ### 5.5 사석 확인 단계 (사활 합의) 1. 진입 시 서버가 "사석 후보"를 자동 제안한다(아래 휴리스틱). 제안은 참고용이며 최종은 합의로 정한다. 2. 두 플레이어는 연결(정확히는 같은 색의 "그룹": 같은 색 돌들 중 빈칸·상대 사석만을 거쳐 이어지는 묶음)을 탭해서 사석/생석을 토글한다. 빈 영역을 탭해서 빅(세키) 표시를 토글할 수 있다. 3. 표시가 바뀌면 양쪽 `agreed`가 모두 해제된다. 현재 표시를 기준으로 계가 미리보기가 실시간으로 갱신된다. 4. 두 플레이어가 같은 표시 상태에 대해 모두 "동의"하면 계가 확정 → 종료. 5. 어느 한쪽이 "이의 – 대국 재개"를 누르면 표시를 모두 버리고 `playing`으로 복귀한다. 재개 후 첫 수는 재개를 요청한 사람의 상대가 둔다(일본기원 규약 제9조와 같은 방식). 재개 후 다시 연속 2패스가 나오면 5.5를 다시 진행한다. 6. 사석 확인 단계에서 시계는 멈춘다. 대신 `scoringDeadlineSec` 제한이 있다(8.5). - 자동 제안 휴리스틱(단순·결정적): (a) 활로 1개인 연결 중 그 활로에 상대가 두면 따내지고 되따기도 불가능한 것, (b) 상대 영역(상대 돌로만 둘러싸인 빈 영역)에 완전히 갇혀 있고 그 영역 안에서 두 눈(서로 떨어진 두 개 이상의 단독 빈 영역)이 없는 연결. 오판이 있어도 플레이어가 고치면 되므로 단순하게 둔다. 향후 KataGo 같은 엔진 기반 추정은 별도 작업으로 분리. ### 5.6 공배와 빅(세키) - 공배(dame): 흑·백 양쪽 생석에 모두 닿은 빈 영역. 아무의 집도 아니다. - 빅(세키): 서로 따낼 수 없이 공배를 공유하며 사는 형태. `territory`에서는 빅 안의 집(눈)은 집으로 세지 않는다(한국기원·일본 규칙). `area`에서는 빅의 돌과 그 눈은 해당 색 영역으로 센다. - 빅 자동 추정(사석 확인 단계 진입 시 제안): 한 색 C의 돌로만 둘러싸인 빈 영역 R에 대해, R을 둘러싼 C 연결 중 하나라도 "R 밖의 활로가 모두 공배이고 그 공배가 상대 생석 연결의 활로이기도 한" 경우 R을 빅 후보로 표시. 플레이어가 최종 수정한다. ## 6. 승패와 점수 계산 ### 6.1 계가 알고리즘 (공통 전처리) 1. 합의된 사석을 판에서 제거하고, 제거한 돌 수를 상대의 포로에 더한다(`territory`에서만 의미 있음). 2. 빈 교차점을 상하좌우 연결로 영역 분할(flood fill). 3. 각 영역의 경계 돌 색 집합을 구한다. - 흑만 → 흑 영역, 백만 → 백 영역, 둘 다 또는 없음(빈 판) → 중립(공배). - 빅으로 표시된 영역 → `territory`에서는 중립, `area`에서는 경계 색의 영역. ### 6.2 `territory` (한국·일본식, 기본) - 흑 점수 = 흑 영역 교차점 수 + 흑이 따낸 돌(대국 중 + 사석) - 백 점수 = 백 영역 교차점 수 + 백이 따낸 돌 + 덤 - 한국 기원식 실물 계가(따낸 돌로 상대 집 메우기)와 결과가 같다: `(흑집 - 백포로) - (백집 - 흑포로) = (흑집 + 흑포로) - (백집 + 백포로)`. - 자기 집 안에 착수하면 그 점은 집이 아니게 되므로 1집 손해, 상대 집 안에 착수해 결국 사석이 되면 상대 포로 +1 — 일본식 규칙과 동일하게 자연히 반영된다. ### 6.3 `area` (중국식) - 흑 점수 = 판 위 흑 생석 수 + 흑 영역 수 - 백 점수 = 판 위 백 생석 수 + 백 영역 수 + 덤 (+ 접바둑이면 치석 수 N) - 포로는 세지 않는다. 공배는 아무에게도 주지 않는다(중국 규칙의 공배 나누기는 쓰지 않음; 모든 공배를 메운 결과와 같아지도록 사용자에게 "공배를 메운 뒤 패스하세요" 안내). ### 6.4 예시 (9줄) - 흑이 E열(x=4) 전체 9개, 백이 F열(x=5) 전체 9개를 이어 판을 둘로 나눔. 흑 쪽(A~D열 36점) 안에 백 사석 1개(B5). 대국 중 흑이 따낸 돌 2개, 백이 따낸 돌 3개. - `territory`, 덤 6.5: 흑 = 36(B5 포함) + 2 + 1 = 39, 백 = 27(G~J열) + 3 + 6.5 = 36.5 → 흑 2.5집 승. - `area`, 덤 7.5: 흑 = 9 + 36 = 45, 백 = 9 + 27 + 7.5 = 43.5 → 흑 1.5점 승. ### 6.5 승패와 동점 - 점수가 높은 쪽 승. 표시: "흑 2집 반 승"(`territory`) / "흑 1.5점 승"(`area`). - 덤이 정수일 때만 동점(빅/무승부, `reason: 'jigo'`) 가능. 기본 덤은 0.5 단위라 무승부 없음. - 그 외 종료: 불계(기권, `resign`), 시간패(`timeLoss`), 무승부 합의(`drawAgreed`), `koRule=korean`의 반복 무승부(`repetition`). ## 7. 지역 룰 / 하우스 룰 (옵션으로 켜고 끄기) - 한국기원식(기본): `territory` + 덤 6.5 + 빅 안의 집 불인정. 패 규칙만 동형 반복 금지로 단순화(5.3 근거). 순수 한국기원식을 원하면 `koRule=korean`. - 중국식: `area` + 덤 7.5 + 접바둑 치석 보정. - 덤 없는 바둑(친선 "맞바둑 덤 없음"): `komi = 0` (무승부 가능). - 접바둑 자유 치석(흑이 원하는 곳에 배치)은 v1 미지원. - 초읽기 대신 피셔 방식도 선택 가능. ## 8. 엔진 설계 ### 8.1 상태(State) ```ts type Color = 'black' | 'white'; type Cell = 0 | 1 | 2; type Pt = { x: number; y: number }; interface BadukState { options: BadukOptions; size: 9 | 13 | 19; board: Cell[]; // y*size + x players: Record; turn: Color; phase: 'playing' | 'scoring' | 'finished'; captures: Record; // 각 색이 따낸 상대 돌 수(대국 중) consecutivePasses: number; moves: ({ kind: 'place'; color: Color; pt: Pt; captured: Pt[] } | { kind: 'pass'; color: Color })[]; positionHistory: string[]; // 슈퍼코: 착수 결과 배치 해시 (Set으로 재구성) situationCounts: Record; // koRule=korean: (배치+차례) 등장 횟수 koPoint: Pt | null; // koRule=korean의 단순 패 금지점 scoringMarks: { dead: number[]; // 사석으로 표시된 교차점 index seki: number[]; // 빅으로 표시된 빈 영역의 대표 index agreed: Record; startedAt: number; resumeRequestedBy: Color | null; } | null; clock: { mainMs: Record; periodsLeft: Record; inByoyomi: Record; turnStartedAt: number; }; undo: { usedBy: Record; pending: { by: Color; plies: 1 | 2 } | null }; draw: { pendingBy: Color | null; lastOfferMove: Record }; result: BadukResult | null; rng: RngState; } ``` ### 8.2 액션 | type | payload | 누가 / 언제 | 검증 조건 | |---|---|---|---| | `place` | `{ x, y }` | 차례인 플레이어, `playing` | 판 안, 빈칸, 자충수 아님("둘 곳의 활로가 없어 둘 수 없어요"), 패 규칙 위반 아님("패는 바로 되따낼 수 없어요. 다른 곳에 한 수 두고 오세요" / "같은 모양이 반복되어 둘 수 없어요") | | `pass` | `{}` | 차례인 플레이어, `playing` | 항상 가능. 연속 2회째면 `scoring` 진입 | | `toggleDead` | `{ x, y }` | 두 플레이어, `scoring` | 그 점에 돌이 있어야 함. 해당 그룹 전체 토글, 양쪽 `agreed` 해제 | | `toggleSeki` | `{ x, y }` | 두 플레이어, `scoring` | 빈 교차점. 해당 빈 영역 토글, `agreed` 해제 | | `agreeScore` | `{}` | 두 플레이어, `scoring` | 본인 `agreed = true`. 둘 다 true면 계가 확정, 종료 | | `resumePlay` | `{}` | 두 플레이어, `scoring` | 표시 초기화, `playing` 복귀, 차례 = 요청자의 상대, `consecutivePasses = 0` | | `requestUndo` | `{}` | 플레이어, `playing` | `undo != off`, 횟수 남음, 대기 요청 없음, 본인 수(착수 또는 패스) 존재. 1수 또는 2수 | | `respondUndo` | `{ accept }` | 상대 | 수락 시 `moves`를 처음부터 재생해서 판·포로·`positionHistory`·`koPoint` 재구성(역연산보다 안전). 시계는 되돌리지 않음 | | `offerDraw` | `{}` | 플레이어, `playing` | `drawOffer=true`, 대기 없음, 직전 거절 이후 본인 5수 이상 | | `respondDraw` | `{ accept }` | 상대 | 수락 → 무승부 | | `cancelOffer` | `{}` | 요청자 | 대기 요청 취소 | | `resign` | `{}` | 플레이어, `playing`/`scoring` | 언제든 | | `timeout` | `{}` | 시스템 | 8.5 | - 대기 요청은 요청받은 쪽이 `place`/`pass`를 하면 자동 거절. - 시계 처리(`place`/`pass` 시, `byoyomi`): `elapsed = now - turnStartedAt`. 기본 시간이 남아 있으면 먼저 차감, 부족분은 초읽기에서 처리: 초읽기 1회 시간 안이면 그 회차 유지(다음 수에 다시 전체 `periodSec`), 넘기면 넘긴 만큼 회차 소진. `periodsLeft`가 0이 되는 순간 이미 시간패이므로 그 액션은 거부. - 이벤트: `stonePlaced`(따낸 좌표 포함), `captured`, `pass`, `atari`(힌트용), `scoringStarted`, `marksChanged`, `playResumed`, `gameEnded` 등. ### 8.3 공개/비공개 정보 (view) - 모두 공개(플레이어·관전자 동일): 판, 차례, 포로 수, 기보, 단계, 사석/빅 표시와 계가 미리보기, 양쪽 동의 여부, 시계(기본 시간, 초읽기 남은 횟수, `deadline`), 대기 중인 요청, 결과. - 차례인 플레이어에게만 편의 정보: `illegalPoints`(패·자충으로 둘 수 없는 점), `atariWarnings`. - view에서 제외: `rng`, `positionHistory`(크기 문제로 제외, 필요하면 기보로 재구성), `situationCounts`. ### 8.4 랜덤 요소 (시드 RNG 사용 지점) - `colorAssignment=nigiri`의 흑백 결정 1회뿐. 대국 진행에는 RNG를 쓰지 않는다. ### 8.5 타이머·시간 초과·연결 끊김 시 자동 행동 - `deadline(state)`: - `playing` + `byoyomi`: `turnStartedAt + mainMs[turn] + periodsLeft[turn] * periodSec*1000` (현재 회차를 다 쓰면 다음 회차가 이어지므로 이 합이 최종 시간패 시각) - `playing` + `fischer`: `turnStartedAt + mainMs[turn]` - `playing` + `none`: `turnStartedAt + idleLimitSec*1000` - `scoring`: `scoringMarks.startedAt + scoringDeadlineSec*1000` - `finished`: `null` - `activePlayers`: `playing`이면 차례인 1명. `scoring`이면 아직 `agreed`하지 않은 플레이어 전원(동시 행동 단계). - `onTimeout(state, player)` → `{ type: 'timeout' }`. `apply` 처리: - `playing`: 해당 플레이어 시간패 (`timeLoss`). 바둑은 자동 착수를 하지 않는다(무작위 수는 판을 망치므로). - `scoring`: 시간 내 합의하지 못한 플레이어는 현재 표시에 동의한 것으로 간주(`agreeScore`). 두 사람 모두 미응답이면 현재 표시대로 계가 확정. 표시가 비어 있으면 모든 돌을 생석으로 계가. - 연결 끊김: 서버는 끊긴 플레이어가 행동해야 할 때 `min(deadline, 끊김 + disconnectGraceSec)`에 `onTimeout` 호출. 시간 제한이 긴 19줄에서도 방치가 길어지지 않게 하기 위함. ### 8.6 종료 조건과 결과(GameResult) ```ts interface BadukResult { ranking: { playerId: PlayerId; rank: 1 | 2 }[]; // 무승부면 둘 다 1 winner: Color | null; reason: 'score' | 'jigo' | 'resign' | 'timeLoss' | 'drawAgreed' | 'repetition'; score?: { method: 'territory' | 'area'; black: { territory: number; captures: number; stones: number; total: number }; white: { territory: number; captures: number; stones: number; komi: number; handicapComp: number; total: number }; margin: number; // 승자 기준 차이 (예: 2.5) ownership: (0 | 1 | 2)[]; // 교차점별 귀속(표시용) }; summaryKo: string; // 예: "흑 2집 반 승", "백 불계승", "흑 시간승" } ``` ## 9. UI/UX - 모바일 세로: 상단 상대 정보(따낸 돌, 시계 + 초읽기 남은 횟수 점 3개), 가운데 정사각 판, 하단 내 정보와 버튼(패스, 무르기, 무승부, 기권, 규칙 보기). - 19줄은 교차점 간격이 약 18px라 "탭 → 미리보기 돌 + 확대 돋보기 → 확인 버튼" 2단계 착수가 기본. 9줄은 한 번 탭 착수 옵션 제공. - 마지막 수 표시, 따낸 돌 사라지는 애니메이션과 효과음(끌 수 있음), 단수 경고(옵션) 시 해당 연결 테두리 깜빡임. - 패/자충 금지점을 탭하면 이유 말풍선. - 초읽기 진입 시 음성/효과음 카운트("10, 9, …")와 화면 테두리 색 변화(어르신 배려: 큰 숫자). - 패스 버튼은 실수 방지를 위해 확인 모달. 상대가 패스하면 "상대가 패스했어요. 끝내려면 패스하세요" 안내. - 사석 확인 단계: 판 위에 사석은 반투명 + ×, 집은 작은 사각 표시, 하단에 "흑 39 : 백 36.5" 미리보기, 큰 "동의" / "이의(대국 재개)" 버튼. 상대가 표시를 바꾸면 바뀐 그룹을 강조. - 규칙 보기: 따내기, 자충수, 패, 집 세는 법 그림 설명. 초보 모드에서 9줄 추천. - 관전자: 계가 미리보기 보기 가능, 버튼 없음. ## 10. 테스트 체크리스트 - [ ] 1점 따내기, 여러 연결 동시 따내기, 가장자리·귀에서 따내기. - [ ] 자충수 거부. 단, 놓는 순간 상대를 따내서 활로가 생기는 수는 합법. - [ ] 단순 패: 따낸 직후 바로 되따기 거부, 다른 곳 한 수(팻감) 후 되따기 허용. - [ ] `positionalSuperko`: 삼패 순환에서 이전 배치를 재현하는 수가 거부되는지. - [ ] `koRule=korean`: 같은 국면(배치+차례) 3회째에 무승부 종료. - [ ] 연속 2패스 → `scoring`. 패스-착수-패스는 진입 안 함. - [ ] 사석 토글 후 상대가 동의해 있던 상태가 해제되는지, 두 사람 동의 시 계가 확정. - [ ] 이의 → 재개 후 첫 수 차례가 요청자의 상대인지, 재개 후 다시 2패스 시 재진입. - [ ] 6.4 예시 국면에서 `territory`/`area` 점수가 39 : 36.5, 45 : 43.5로 계산. - [ ] 빅 영역: `territory`에서 빅 안 눈이 집으로 안 세어지고, `area`에서 세어짐. - [ ] 접바둑 N=2~9 배치가 표와 일치, 백이 먼저 둠, 덤 0.5, `area`에서 백 +N 보정. - [ ] 초읽기: 기본 시간 소진 후 30초 안에 두면 회차 유지, 넘기면 회차 감소, 마지막 회차 초과 시 시간패, 그 뒤 도착 착수 거부. - [ ] `scoring` 단계 시간 초과 → 미응답자 자동 동의 후 계가. - [ ] 연결 끊김 유예 후 시간패, 재접속 시 유예 해제. - [ ] 무르기 수락 시 따낸 돌이 복원되고 포로 수·슈퍼코 이력이 재생으로 정확히 복원. - [ ] 정보 누출: view에 `rng`, `positionHistory`, `situationCounts`가 없는지. 관전자 view에 `illegalPoints`/`atariWarnings` 없음. - [ ] 리플레이 결정성: 같은 시드·액션 로그 → 같은 결과. ## 11. 참고 자료 - 한국기원 바둑 규칙 안내: https://www.baduk.or.kr/story/badukRule.asp - 나무위키 「계가」: https://namu.wiki/w/%EA%B3%84%EA%B0%80 , 「삼패」: https://namu.wiki/w/%EC%82%BC%ED%8C%A8 , 「바둑/국가별 룰」: https://namu.wiki/w/%EB%B0%94%EB%91%91/%EA%B5%AD%EA%B0%80%EB%B3%84%20%EB%A3%B0 - 위키백과 「덤 (바둑)」: https://ko.wikipedia.org/wiki/%EB%8D%A4_(%EB%B0%94%EB%91%91) - 일본기원 규약(1989) 영문: https://www.cs.cmu.edu/~wjh/go/rules/Japanese.html (사활 다툼 시 재개, 빅 안의 집 불인정) - Sensei's Library "Superko", "Handicap placement": https://senseis.xmp.net/?Superko , https://senseis.xmp.net/?HandicapPlacement - Tromp-Taylor 규칙(영역 계산·동형 반복 금지의 간결한 정의): https://tromp.github.io/go.html ## 12. 메모 (상표·법적 주의 등) - "바둑", "Go", "Weiqi", "Baduk"은 전통 게임 명칭으로 상표 문제 없음. "한국기원 공인" 같은 표현은 쓰지 않는다. - 사활 자동 추정은 보조 기능일 뿐이며, 결과는 반드시 두 플레이어의 합의로 확정된다는 점을 UI에 명시. - 금전·베팅 요소 없음.