매듭 풀기
엉킨 비단 끈의 구슬을 옮겨 겹치는 줄을 없앤다 — 다 풀리면 전통 매듭이 맺힌다.
프롬프트를 복사해 claude.ai 에 붙여 넣으면 바로 실행됩니다 · Opus 5.5 · Effort High 기준
- 권장 모델
- Claude Opus 5.5 · Effort High
- 화면비
- 1:1 (정사각)
- 조작
- 구슬 끌기 · 실마리는 H 또는 단추 · 키보드는 Tab으로 고르고 방향키로 옮기기
- 결과물
- HTML 파일 하나 · 따로 설치할 것 없음
프롬프트
Claude 가 읽는 제작 지시문입니다. 맨 위 [바꿀 곳]의 값을 바꿔 붙여 넣어도 됩니다.
브라우저에서 바로 도는 퍼즐 게임 「매듭 풀기」를 HTML 파일 하나로 만들어 줘.
핵심 아이디어: 한지 위에 붉은 비단 끈이 엉켜 있다. 끈은 금빛 구슬(매듭 점) 사이를 잇는 꼰 실이다. 구슬을 끌어 옮겨 서로 겹치는 끈이 하나도 없게 하면(평면 그래프 풀기), 그 순간 끈이 저절로 당겨지며 구슬들이 미리 정해 둔 자리로 미끄러져 전통 매듭(도래매듭·국화매듭) 모양으로 맺히고, 아래로 술이 툭 떨어진다. 퍼즐의 정답 배치가 곧 매듭 모양이다 — 판을 만들 때 매듭 모양 배치(겹침 0)를 먼저 정하고, 그 점들을 원 둘레에 옮겨 놓고 겹침 수가 정해진 범위에 들 만큼만 뒤섞어 엉킨 판을 만든다. 매듭을 풀면 그 자리에서 다음 매듭이 맺힌 채로 나타났다가 스스로 풀려 엉킨다.
시그니처 순간: 겹침이 0 이 되는 순간부터 1.9초 동안, 화면 가운데에서 지름 약 0.64S 의 매듭이 맺힌다(S 는 화면 짧은 변). 구경 모드에서는 열린 뒤 9초 안에 첫 매듭이 다 맺힌다.
[바꿀 곳]
- seed: 7 — 첫 판 시드. 판마다 1씩 는다. 구경 모드는 seed + 1000 부터 쓴다.
- cordColor: '#b8333b' (다홍 비단 — 풀린 끈), cordDark: '#7e1d27' (꼰 결 그림자), cordLight: '#e2735f' (결 하이라이트)
- tangledColor: '#9a8f84' (겹친 끈 — 바랜 색), tangledDark: '#6e655d'
- beadColor: '#c9a24a' (금빛 구슬), beadRim: '#8a6a2a'
- paperColor: '#ece3d2' (한지 바탕), fiberColor: '#d6c9b0' (한지 섬유), inkColor: '#3a322d' (먹 — 글자)
- timeBase: 12, timePerNode: 2.5, timeCap: 34 — 매듭 하나의 제한 시간(초) = min(timeCap, timeBase + timePerNode × 점 개수)
- hintCost: 3 — 실마리 한 번에 깎이는 시간(초)
- pointsPerCross: 10, solveBonusPerLevel: 100, secondBonus: 5
- volume: 0.35
[크기]
- W·H 는 창 크기, S = min(W, H). 모든 크기는 S 의 배수다.
- 게임판은 한 변 S 인 정사각형으로 창 가운데에 둔다. 판 밖 남는 곳도 같은 한지 바탕으로 칠한다.
- 매듭 점의 좌표는 「단위 좌표」(가로·세로 −1~1)로 저장하고, 화면 좌표 = 창 가운데 + 단위 좌표 × h 로 바꾼다. h = 0.40S. 다만 세로로 긴 화면(H ≥ 1.3W, 폰 세로)에서는 위아래가 남으므로 h = 0.46S 로 키운다(x 끝 0.95 × 0.46S + 구슬 0.02S = 0.457S < 0.5S 라 옆으로 넘치지 않는다).
- 점을 끌 수 있는 범위: 단위 좌표 x −0.95~0.95, y −0.85~0.85 (가로 1280·세로 720 에서 y 화면 범위 0.16S~0.84S — 위쪽 글자 줄(0~0.14S)과 아래 실마리 단추(0.88S~)를 덮지 않는다. 390×844 에서는 y 270~574px).
- 구슬 반지름 0.02S, 잡기 판정 반지름 0.055S(가장 가까운 구슬을 잡는다).
- 끈 굵기 w = 0.016S. 꼰 결 간격 0.9w.
- 맺힌 매듭: 바깥 점이 단위 반지름 0.80 → 화면 반지름 0.32S(폰 세로 0.368S), 지름 약 0.64S(폰 세로 0.74S) 이상.
- 위쪽 글자 줄은 언제나 **창 맨 위**(y 0~0.14S)에 붙는다 — 폰 세로에서도 판 위쪽이 아니라 창 맨 위다. 가로 자리의 기준은 판 정사각형의 왼쪽 끝 L·오른쪽 끝 R(폰 세로에서는 L = 0, R = W). 글자 셋이 서로 겹치지 않도록 줄을 둘로 나눈다:
· 첫째 줄(글자 세로 가운데 y = 0.05S, 글자 높이 0.04S): 왼쪽 점수 — x = L + 0.04S 에서 왼쪽 정렬, 너비 한도 0.36S. 오른쪽 엇갈림 — 오른쪽 끝 x = min(R − 0.04S, 소리 단추 왼쪽 끝 − 0.02S) 에 오른쪽 정렬, 너비 한도 0.30S. 두 글자 사이에는 아무것도 두지 않는다.
· 둘째 줄(y = 0.095S, 글자 높이 0.034S, 맺힘 때 0.046S): 가운데 정렬 제목(매듭 이름) — 너비 한도 0.72S.
· 남은 시간 끈: y = 0.13S, 가운데 정렬, 길이 최대 0.6S.
· 「너비 한도」는 measureText 로 재서 넘치면 글자 크기를 그 비율만큼 줄여 맞춘다(말줄임 없음). 390×844 기준(S = 390): 소리 단추는 x 351~378px·y 12~39px. 점수는 x 16~156px 안(y 12~27px). 엇갈림은 오른쪽 끝 343px 에서 왼쪽으로 최대 117px, 곧 x 226~343px 안(y 12~27px) — 점수와 70px 떨어진다. 제목은 둘째 줄 x 55~335px·y 28~46px 안 — 첫째 줄 아래라 점수·엇갈림과 포개질 수 없고, 오른쪽 끝 335px 가 소리 단추 왼쪽 351px 보다 왼쪽이다. 1440×900 기준(S = 900, L = 270, R = 1170): 점수 x 306~630px, 엇갈림 x 864~1134px, 제목 x 396~1044px.
- 실마리 단추: 창 기준 가운데 x = 0.5W, 가운데 y = H − 0.075S, 너비 0.36S, 높이 0.09S, 모서리 둥글기 0.045S. (세로 390×844 에서 y 0.945H~0.986H, 가로 1280×720 에서 0.880H~0.970H — 두 경우 모두 y = 0.955H 가 단추 안이다.)
- 소리 끄기 단추: 창 오른쪽 위, 지름 0.07S, 창 위·오른쪽 가장자리에서 0.03S 안쪽(왼쪽 끝 x = W − 0.10S).
- 술: 길이 0.11S. 가로 화면에서는 술 끝이 약 0.95H 까지 내려와 실마리 단추·「눌러서 시작」 자리(0.88H~0.97H)를 지나간다 — 그래서 맺힘 연출 동안 그 자리의 단추와 글자는 모두 숨긴다(다음 절에 자세히).
[장면]
바탕 — 한지. paperColor 로 창 전체를 칠하고, 시작할 때 오프스크린 캔버스에 섬유 320가닥을 미리 그려 둔다: 길이 0.01S~0.04S 의 살짝 휜 가는 선(굵기 0.0015S), fiberColor, 불투명도 0.25~0.45, 방향은 제멋대로. 창 가장자리 쪽으로 아주 옅게 어두워지는 비네트(가장자리 '#e0d3bb'). 그 밖의 장식은 없다.
매듭 판(그래프) — 판마다 아래 정해진 「매듭 배치」(정답, 겹침 0)를 쓴다. 모두 단위 좌표, y 는 아래가 +.
- 첫째 매듭 「도래매듭」: 점 8개, 끈 12개. 모서리 점 c0~c3 은 반지름 0.36, 각도 45°+90°k. 끝 점 t0~t3 은 반지름 0.80, 각도 90°k. 끈: 사각 c_k–c_(k+1) 4개, 끝 점 t_k–c_k 와 t_k–c_(k−1) 8개.
- 둘째부터 「국화매듭」 n잎: 둘째 n=5, 셋째 n=6, 넷째 n=7, 다섯째부터 n=8(시드만 바뀐다). 가운데 점 1개(0,0), 안쪽 점 i_j 는 반지름 0.34, 각도 −90° + 360°·j/n, 바깥 점 o_j 는 반지름 0.80, 각도 −90° + 360°·(j+0.5)/n. 끈: 가운데–i_j, i_j–i_(j+1), o_j–i_j, o_j–i_(j+1), o_j–o_(j+1). 점 2n+1개, 끈 5n개(n=5 → 11점 25끈, n=8 → 17점 40끈).
- 끈마다 「휨」 값과 「휨 방향」이 있다. 휨은 맺힌 모습에서만 쓴다: 끈 A→B 를 이차 곡선으로 그리고, 조절점 = 가운데점 + 방향 단위벡터 × 휨 × 끈 길이.
· 도래: 사각 끈 0.18, 끝 점 끈 0.22 — 방향은 끈 가운데점에서 판 중심(0,0) 반대쪽.
· 국화의 꽃잎 끈 o_j–i_j·o_j–i_(j+1): 휨 0.30, 방향은 「꽃잎 축」(원점 → o_j 직선)에서 멀어지는 쪽 법선. 그래서 한 꽃잎의 두 끈이 서로 반대로 불룩해져 i_j → o_j → i_(j+1) 이 둥근 잎(고리)이 된다. 곧은 선으로 남기면 별 모양으로 읽히므로 이 휨이 국화의 핵심이다.
· 국화의 잎 사이 끈 o_j–o_(j+1): 휨 0.22, 방향은 판 중심 **쪽**(안으로 오목). 바깥으로 불룩하게 하면 꽃잎을 둥근 테가 둘러싼 원처럼 읽히므로 반드시 안쪽으로 오목하게 — 잎 끝끼리 이어지며 잎 사이에 골이 파인다.
· 국화의 안쪽 고리 i–i: 0.15, 판 중심 반대쪽(꽃술 테두리). 가운데–i_j(꽃술 살): 0.
· 맺힌 국화의 기대 모양: 가운데 작은 둥근 꽃술 둘레로 둥근 잎 n장이 돌아가고, 잎 끝 사이가 오목하게 파인 꽃. 원·별로 보이지 않는다.
- 엉킨 판 만들기 — 겹침 수를 정해진 범위 안에 넣는다. 원 둘레에 아무렇게나 섞으면 국화 다섯 잎(25끈)도 겹침이 60~90개로 치솟아 34초 안에 풀 수 없다. 그래서:
1) 매듭 배치의 각 점을 원점에서 본 각도 순서대로(가운데 점은 시드 난수로 고른 아무 칸) 반지름 0.78 의 원 둘레 같은 간격 칸에 놓는다. 이 상태는 겹침이 적다.
2) 두 칸을 시드 난수로 골라 맞바꾸고 겹침을 다시 센다. 맞바꾼 뒤 겹침이 범위 최대를 넘으면서 맞바꾸기 전보다도 많아졌으면 그 맞바꿈을 되돌린다(처음부터 최대를 넘었다면 줄이는 맞바꿈만 남는다). 겹침이 범위 안에 들 때까지 되풀이한다(최대 400번, 그래도 범위 밖이면 console.warn 하고 범위에 가장 가까웠던 상태를 쓴다).
3) 끝으로 각 점을 ±0.05 흔든다(흔든 뒤 다시 세어 범위 밖이면 흔들기를 취소).
겹침 범위(최소~최대): 도래 4~10, 국화 다섯 잎 9~16, 여섯 잎 11~19, 일곱 잎 13~22, 여덟 잎 15~25.
겹침 판정 — 끝점을 공유하지 않는 두 선분이 서로 지나가면 한 번 겹침이다(한 점에서 만나거나 겹쳐 놓인 경우도 겹침). 구슬이 자기와 이어지지 않은 끈 위에 단위 거리 0.012 안으로 놓여도 겹침 하나로 센다. 겹침 수는 점이 움직일 때마다 바로 다시 센다(끈 40개라도 780쌍이라 충분히 빠르다).
꼰 실 그리기(이 작품의 얼굴) — 끈 하나를 점 목록(직선이면 두 점, 곡선이면 24점으로 나눈 점)으로 받아 그린다:
1) 그림자: (0.004S, 0.005S) 비켜 rgba(60,40,30,0.18), 굵기 w.
2) 바탕 줄: 굵기 w, 끈 색(풀린 끈 cordColor, 겹친 끈 tangledColor).
3) 꼰 결: 끈을 따라 0.9w 마다 짧은 비스듬한 획 — 법선 쪽 −w/2·진행 쪽 −0.35w 인 점에서 법선 쪽 +w/2·진행 쪽 +0.35w 인 점까지, 굵기 0.22w, 어두운 색(cordDark 또는 tangledDark). 한 색의 획은 path 하나에 모아 한 번에 stroke 한다.
4) 윤기: 법선 쪽 −0.22w 로 비킨 가는 줄, 굵기 0.18w, cordLight 불투명도 0.5(겹친 끈은 0.2).
결의 시작 위치에 phase 를 두어, 시그니처 때 결이 끈을 따라 흘러가게 한다.
그리는 순서: 겹친 끈 먼저, 풀린 끈 나중(풀린 끈이 위로 지나간다). 두 끈이 겹친 곳마다 먹색 '#5a4a44' 작은 점(반지름 0.006S)을 찍어 어디가 엉켰는지 보이게 한다.
구슬 — 반지름 0.02S, beadColor, 테두리 beadRim 0.004S, 왼쪽 위에 흰 반점(반지름 0.006S, 불투명도 0.6). 잡은 구슬은 1.25배, 키보드로 고른 구슬은 바깥에 먹색 고리(반지름 0.032S, 굵기 0.003S).
위쪽 글자 줄(창 맨 위 0~0.14S, 자리는 앞 절의 두 줄 배치 그대로) — 첫째 줄 왼쪽: 「점수 1234」, 첫째 줄 오른쪽: 「엇갈림 7」. 둘째 줄 가운데: 「첫째 매듭 · 도래매듭」 꼴. 첫째 줄 가운데에는 아무 글자도 두지 않는다 — 가운데 제목을 점수·엇갈림과 같은 줄에 두면 좁은 폰 화면에서 서로 포개진다. 그 아래 y = 0.13S 에 남은 시간을 보여 주는 가로 끈 하나 — 같은 꼰 실 그리기로, 가운데 정렬, 길이 = 0.6S × 남은 시간/제한 시간. 5초 아래로 떨어지면 tangledColor 로 바뀌고 굵기가 초당 2번 1.0~1.3배로 맥박친다.
시그니처 — 「매듭이 맺힌다」. 겹침 수가 0 이 된 그 프레임을 t=0 으로:
- 0~0.3초: 모든 끈이 cordLight 쪽으로 밝아졌다 돌아온다(빛이 한 번 지나감). 제한 시간 멈춤. 잡고 있던 구슬은 놓는다.
- 0.3~1.5초: 구슬마다 지금 자리에서 「매듭 배치 자리 × 1.08」(조금 느슨한 자리)로 easeInOutCubic 으로 미끄러진다. 끈의 휨은 0 → 정해진 값. 꼰 결의 phase 가 초당 3w 로 흘러 끈이 당겨지는 듯 보인다. 구슬 반지름은 0.6배로 줄고 색이 cordColor 로 섞여 끈의 맺힌 마디처럼 보인다.
- 1.5~1.9초: 그 배율이 1.08 → 1.0 으로 easeOutBack 조여들어 구슬이 정확히 매듭 배치 자리에 선다. 1.5초에 「툭」 소리.
- 1.5~2.3초: 술이 떨어진다 — 매듭 배치에서 가장 아래 점 밑 (0, 가장 큰 y + 0.06) 단위 좌표에서 시작해, 짧은 고리와 금빛 띠(높이 0.012S) 아래로 가는 실 36가닥, 길이 0 → 0.11S(easeOutBack), 아래 끝 너비 0.06S, 가닥마다 cordColor·cordDark 사이 색, sin(시간×2) × 0.01S 로 살랑인다.
- 1.6~2.0초: 둘째 줄 제목이 매듭 이름(「도래매듭」·「국화매듭 다섯 잎」)으로 바뀌며 0.034S → 0.046S 로 커지고 cordColor 로 물든다(4.1초에 되돌아감, 너비 한도 0.72S 는 그대로). 얻은 점수 「+260」 은 첫째 줄 점수 글자 바로 오른쪽(0.01S 띄움, 0.03S 글자, 점수 칸 너비 한도 0.36S 안)에 나타나 1초 동안 사라진다 — 둘째 줄 제목 쪽으로 내려가지 않는다. 매듭 위에는 글자를 얹지 않는다.
- 2.0~3.2초: 그대로 보여 준다.
- 3.2~3.5초: 바꿔 맺기 — 맺힌 지금 매듭(끈·구슬·술)이 불투명도 1 → 0 으로 사라지는 동안, 같은 자리에 **다음 매듭이 맺힌 모습**(다음 매듭 배치 자리, 휨 1, 풀린 끈 색)이 0 → 1 로 겹쳐 나타난다. 점 개수가 달라도(8 → 11) 이렇게 맞바꾸므로 구슬 짝을 지을 필요가 없다. 매듭을 한 점으로 줄이거나 가운데서 퍼뜨리지 않는다.
- 3.5~4.1초: 풀려 엉키기 — 다음 매듭의 구슬마다 매듭 배치 자리에서 엉킨 판 자리로 easeInOutCubic 으로 저마다 흩어져 간다. 휨은 1 → 0, 겹침·끈 색은 움직이는 동안 실시간으로 바뀐다(맺힌 꽃이 풀려 엉키는 것이 보인다). 구슬 크기·색도 0.6배 끈색 → 원래 구슬로.
- 4.1초: 제한 시간이 새로 시작하고 실마리 단추가 다시 나타난다.
실마리 단추(플레이)와 「눌러서 시작」 글자(구경 모드)는 같은 자리에 있고 같은 규칙으로 숨는다: 맺힘 0~1.2초는 그대로, 1.2~1.5초에 불투명도 1 → 0, 1.5~3.8초에는 그리지 않음, 3.8~4.1초에 0 → 1. 술이 1.5~3.5초 동안 그 자리를 지나가기 때문이다. 같은 까닭으로 그 자리 둘레(창 아래쪽, 실마리 단추 사각형 위로 0.02S 까지)에는 맺힘 동안 다른 글자·단추를 두지 않는다.
끝 화면 — 판 위에 한지색 rgba(236,227,210,0.82) 를 덮고, 가운데 위에서 아래로: 끝난 이유 「시간이 다 됐다 — 엇갈림 N개가 남았다」(0.045S, cordColor, 창 가운데 − 0.20S), 「점수 530」(0.1S 굵게, 창 가운데 − 0.07S), 「최고 점수」·「맺은 매듭 N개」(0.04S, 창 가운데 + 0.05S·+0.11S), 실마리 단추 자리에 「누르면 다시 시작」(0.04S, 초당 1번 불투명도 0.6~1.0). 글자마다 너비 한도 0.9S(넘치면 글자를 줄인다). 엉킨 끈은 덮개 아래로 비쳐 보인다.
[조작]
- 끌기(마우스·터치 공통, pointer 이벤트): 구슬을 누르면 잡고, 누른 위치와 구슬 사이 차이를 유지한 채 그 프레임부터 손가락을 그대로 따라온다. 끌 수 있는 범위 밖으로는 안 나간다. 끄는 동안 겹침·끈 색이 실시간으로 바뀐다. 구슬이 아닌 곳을 누르면 아무 일도 없다.
- 실마리 단추를 탭(또는 클릭) / 키보드 H·Enter·Space: 실마리 한 번(겹침을 줄이는 자리로 구슬 하나를 옮겨 주고 시간 3초를 깎는다 — 자세한 것은 다음 절).
- 키보드 Tab 또는 E: 다음 구슬 고르기, Q: 이전 구슬. 방향키 또는 WASD: 고른 구슬을 초당 0.5S 로 옮김(Shift 를 같이 누르면 2배). 판이 시작될 때와 실마리 뒤에는 겹침에 가장 많이 걸린 구슬이 저절로 골라진다.
- M 또는 오른쪽 위 단추: 소리 켜고 끄기.
- 구경 모드·끝 화면에서는 어떤 키·탭이든 새 판을 연다(그 입력은 시작에만 쓰고 실마리로 치지 않는다).
- Tab·Space·방향키는 preventDefault 해서 페이지가 움직이지 않게 한다.
- 폰 세로 화면: 판이 화면 가운데 정사각형, 실마리 단추는 화면 맨 아래라 엄지가 닿는다.
[규칙]
- 새 판은 첫째 매듭의 엉킨 판으로 바로 시작하고(흩어짐 연출 없음), 제한 시간도 그 프레임부터 흐른다. 시드는 판마다 1씩 는다.
- 한 판은 여러 매듭을 차례로 푸는 것이다. 첫째 도래매듭(8점 12끈), 둘째 국화 다섯 잎(11점 25끈), 셋째 여섯 잎(13점 30끈), 넷째 일곱 잎(15점 35끈), 다섯째부터 여덟 잎(17점 40끈).
- 제한 시간 = min(34, 12 + 2.5 × 점 개수): 첫째 32초, 둘째부터 34초. 매듭을 풀면 남은 시간은 점수가 되고 다음 매듭은 새 시간으로 시작한다.
- 점수: 그 매듭에서 가장 적었던 겹침 수보다 지금 겹침이 적어지면 줄어든 수 × 10점(같은 겹침을 되풀어 점수를 벌 수 없다). 매듭을 풀면 100 × 매듭 번호 + 남은 초(내림) × 5.
- 실마리: 겹침에 가장 많이 걸린 구슬(같으면 번호 작은 것)을 골라, 후보 자리 — 끌 수 있는 범위 안 9×9 격자 81곳과 그 구슬의 매듭 배치 자리 — 중 겹침이 가장 적어지는 곳으로 0.25초 동안 easeOutCubic 으로 옮긴다(같으면 지금 자리에 가까운 곳). 지금보다 줄지 않으면 다음으로 많이 걸린 구슬을 본다. 어느 구슬도 줄일 수 없으면 가장 많이 걸린 구슬을 매듭 배치 자리로 옮긴다. 제한 시간에서 3초를 깎는다(1초 아래로는 깎지 않는다). 움직이는 0.25초 동안, 그리고 맺힘·바꿔 맺기·풀려 엉키기 연출(4.1초) 동안 들어온 실마리와 끌기는 무시한다. 점수는 일반 규칙대로 붙는다.
- 제한 시간이 0 이 되면 판이 끝난다: 0.6초 동안 남은 겹침 점마다 다홍 고리가 커지며 깜박이고 끈이 바랜다(state 는 'play'), 끝나면 state = 'over'.
- 아무 입력이 없을 때 가장 길게 버티는 경우 = 맺힘~풀려 엉키기 연출 4.1초 + 34초 + 끝 연출 0.6초 = 38.7초 — 40초 안이다.
- 끝 화면에는 끝난 이유(시간이 다 됐다, 남은 엇갈림 수)를 반드시 글로 보여 준다 — 실패의 이유가 화면에 보여야 다시 하고 싶어진다.
- 난이도 곡선(엉킨 판의 겹침 범위로 묶는다): 첫째 도래매듭 겹침 4~10 — 보통 10~20초에 풀려 처음 20초 안에 질 일이 거의 없다. 둘째 다섯 잎 9~16, 셋째 여섯 잎 11~19, 넷째 일곱 잎 13~22, 다섯째부터 여덟 잎 15~25. 매듭마다 점 2개·끈 5개·겹침 약 3개씩 늘고 시간은 34초로 묶여 빠듯해진다. 기본 설정에서 처음 하는 사람이 실마리를 섞어 쓰면 둘째 매듭까지는 맺을 수 있는 정도다.
- 최고 점수는 메모리에만 둔다.
[구경 모드]
- 열리자마자 'demo'. 구경 모드용 도래매듭이 엉킨 채로 첫 프레임부터 화면을 채우고(빈 화면 없음), 0.2초부터 컴퓨터가 푼다.
- 컴퓨터의 한 수: 실마리와 같은 방법으로 구슬과 자리를 정하고, 반투명 먹색 손가락 고리(반지름 0.03S, 불투명도 0.35)가 그 구슬로 0.35초 동안 날아가 → 잡고(구슬 1.25배) → 0.55초 동안 easeInOutCubic 으로 끌어 옮기고 → 놓은 뒤 0.25초 쉰다. 한 수 1.15초. 같은 끌기 경로를 쓰므로 끈 색·겹침 점이 실제 플레이처럼 바뀐다.
- 수 고르기는 실마리 방법을 따르되, 3수 연달아 겹침이 줄지 않으면 가장 많이 걸린 구슬을 매듭 배치 자리로 옮긴다(배치 자리로만 다 옮기면 반드시 풀리므로 끝이 있다).
- 구경 모드 매듭은 시작 전에 수 고르기를 미리 돌려 보고, 6수를 넘으면 시드를 1씩 늘려 다시 만든다(최대 30번, 그래도 넘으면 console.warn 하고 그대로 쓴다). 그래서 구경 모드 매듭은 늘 6수 안에 풀린다.
- 다 풀리면 시그니처(바꿔 맺기·풀려 엉키기까지)를 그대로 보여 주고, 국화 다섯 잎 → 다시 도래매듭(시드 +1) 으로 끝없이 돈다. 국화 다섯 잎도 같은 방법으로 미리 풀어 보아 12수를 넘으면 시드를 늘린다. 제한 시간·점수·엇갈림·남은 시간 끈은 표시하지 않는다.
- 글자: 창 맨 위 가운데 y = 0.07S 에 제목 「매듭 풀기」(0.05S, 너비 한도 0.6S). 맺힘 동안에는 이 제목이 매듭 이름으로 바뀌어 cordColor 로 물들고 4.1초에 돌아온다. 실마리 단추 자리(가운데 y = H − 0.075S)에 「눌러서 시작」(0.045S, 초당 1번 불투명도 0.6~1.0) — 맺힘 0~4.1초 동안은 [장면]에 적은 대로 숨긴다(술과 겹치지 않게).
- 열린 뒤 첫 매듭: 겹침 0 이 되는 때 ≤ 0.2 + 6 × 1.15 = 7.1초, 다 맺히는 때(+1.9초) ≤ 9.0초 — 10초 안이다.
[소리]
- 모두 WebAudio 합성음, 첫 입력 뒤에만 AudioContext 를 만들거나 resume 한다. 전체 음량 0.35, 오른쪽 위 단추·M 키로 끈다(단추에 켜짐·꺼짐 표시).
- 음계는 평조 5음(Eb4·F4·Ab4·Bb4·C5, 그 위 옥타브).
- 구슬 잡기: 삼각파 330Hz 짧은 튕김 60ms.
- 겹침이 줄 때: 사인+삼각파 튕김, 0.4초 지수 감쇠. 그 매듭에서 줄어든 횟수만큼 5음 위로 한 칸씩 오른다(가야금 줄을 차례로 뜯는 느낌).
- 실마리: 대역 통과 잡음 0.2초 「스윽」.
- 시그니처: 0.3초부터 5음 오름 아르페지오 3음(간격 0.12초), 1.5초 조임에 낮은 북 「툭」(사인 90Hz → 50Hz, 0.25초).
- 시간 끝: 두 음 내림(Bb4 → Eb4).
[구현]
- HTML 파일 하나로 만든다. 바깥 파일·글꼴·라이브러리·네트워크 요청을 쓰지 않는다(미리보기 칸에서 막힌다).
- 첫 <script> 맨 앞에 CONFIG 객체를 두고 [바꿀 곳]의 값과 이 글에 나온 숫자(속도·크기·색·시간)를 이름 붙여 모은다.
- 게임 진행은 requestAnimationFrame 의 타임스탬프로 고정 시간 간격(1/120초) 갱신을 돌린다. 한 프레임에 밀린 시간은 0.1초까지만 따라잡는다. setTimeout·setInterval·CSS 애니메이션으로 움직이지 않는다.
- 난수는 시드 고정 난수(mulberry32 등)만 쓰고, 판마다 시드를 하나씩 늘린다. Math.random 은 쓰지 않는다.
- 캔버스는 늘 창 전체 크기다. 창 크기가 바뀌면 다시 맞추고, 게임판 비율이 정해진 게임은 판을 가운데 두되 남는 곳에도 배경을 그린다(빈 띠를 두지 않는다). 스크롤이 생기지 않게 한다. devicePixelRatio 는 2 까지만 선명도에 반영한다.
- 키보드와 터치를 둘 다 받는다. 키 입력은 window 의 keydown·keyup 으로 받아, 화면을 먼저 누르지 않아도 첫 키가 먹게 한다. 짧게 눌렀다 뗀 키도 놓치지 않게 keydown 때 처리하거나 기록해 둔다. 터치는 페이지 스크롤·확대가 일어나지 않게 막는다(touch-action: none).
- 점수·상태를 window.__game = { state, score } 에 두고 매 프레임 갱신한다. state 는 'demo'(구경 모드)·'play'·'over' 셋 중 하나, score 는 숫자다.
- 열리자마자 'demo' — 컴퓨터가 스스로 플레이하는 구경 모드와 「눌러서 시작」 안내. 첫 키 입력이나 탭이면 새 판 'play'. 판이 끝나면 'over' 화면, 거기서 키 입력이나 탭이면 새 판. 'over' 화면은 뜨자마자 키 입력·탭을 받는다(입력을 막는 대기 시간을 두지 않는다). 끝나는 연출이 있으면 그동안은 state 를 'play' 로 두고, 연출이 끝나 입력을 받을 수 있게 된 때 'over' 로 바꾼다.
- 플레이 중 아무 입력이 없으면 늦어도 40초 안에 판이 끝난다.
- 브라우저 저장소(localStorage·sessionStorage·IndexedDB·쿠키)를 쓰지 않는다 — 미리보기 칸에서 막혀 오류가 난다. 최고 점수는 메모리에만 둔다.
- 소리는 WebAudio 로 합성한 소리만, 첫 입력 뒤에만 낸다. 화면 구석에 소리 끄기 단추(M 키도)를 둔다.
- 탭이 숨으면 멈추고 돌아오면 이어서 한다.
- 글자는 시스템 글꼴만 쓴다: 'Pretendard', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', sans-serif.
- 모든 함수·상수를 먼저 정의하고, 시작(초기화와 첫 requestAnimationFrame)은 스크립트 맨 끝에서 한 번만 부른다.
- 콘솔에 오류가 나지 않게 한다. 스스로 대조하는 표는 console.table, 어긋남은 console.warn 으로만 낸다.
이 작품만의 구현:
- 자료 구조: knot = { name, nodes: 매듭 배치 단위 좌표 목록, edges: [a, b, bend] 목록 }. 판 상태 = 지금 단위 좌표 pos, 겹침 수, 끈마다 겹침 여부, 겹침 점 목록, 그 매듭의 최소 겹침 bestCross.
- 매듭 배치 함수 makeDorae()·makeGukhwa(n) 를 [장면]의 수식 그대로 만든다. 맺힘 연출의 구슬 자리 = 매듭 배치 자리(단위 좌표) — 플레이어가 어떤 모양으로 풀었든 같은 매듭으로 맺힌다.
- 선분 교차는 방향(외적) 판정으로, 끝점 공유 쌍은 건너뛴다. 실마리 후보 평가는 옮길 구슬에 이어진 끈과 나머지 끈만 다시 세서 빠르게 한다.
- 매듭 연출·흩어짐·실마리 이동·구경 모드 손가락은 모두 고정 간격 갱신 안의 시간 변수로 진행한다.
- 실마리 단추·소리 단추의 눌림 판정은 [크기]의 사각형·원 그대로. 'play' 에서 실마리 단추 위 탭은 구슬 잡기보다 먼저 판정한다.
- 기본 설정 합격 기준 — 시작할 때 아래를 계산해 console.table 로 내고, 기대와 다르면 console.warn:
· 매듭 1~5번 각각: 점 수(8·11·13·15·17), 끈 수(12·25·30·35·40), 매듭 배치의 곧은 선 겹침(모두 0), 첫 판 시드로 엉킨 판의 겹침(범위 4~10·9~16·11~19·13~22·15~25 안), 제한 시간(32·34·34·34·34).
· 입력 없이 가장 길게 버티는 시간 4.1 + 34 + 0.6 = 38.7 ≤ 40.
· 위쪽 글자 줄 배치: 지금 창 크기에서 점수·엇갈림·제목·소리 단추의 사각형을 (가장 긴 글 「다섯째 매듭 · 국화매듭 여덟 잎」·「엇갈림 25」·「점수 99999」 로) 재어 서로 겹치는 쌍의 수(기대 0). 창 크기가 바뀔 때마다 다시 잰다.
· 구경 모드 첫 도래매듭을 실제 수 고르기로 미리 풀어 본 수(≤ 6), 다 맺히는 시각 0.2 + 수 × 1.15 + 1.9(≤ 9.0초).
· 맺힌 매듭 지름(단위 지름 × h, 기대 ≥ 0.6S).
- 실마리를 연달아 5번 쓰면 첫째 매듭에서 점수가 0 보다 커야 한다(엉킨 판의 겹침이 4 이상이고 실마리는 겹침을 줄이는 자리를 먼저 고르므로). 이것도 시작할 때 복사본으로 돌려 보고 표에 넣는다.
[하지 말 것]
- 반짝이 입자·꽃잎 흩날림·렌즈 플레어를 넣지 않는다 — 눈이 끈의 결과 맺힘에 머물러야 한다.
- shadowBlur 발광을 끈·구슬·글자에 쓰지 않는다 — 비단의 윤기는 [장면]의 윤기 줄로만 낸다. 발광은 한지 위 비단처럼 보이지 않는다.
- 끈을 단색 직선 하나로 그리지 않는다 — 꼰 실 결이 이 작품의 얼굴이다.
- 바탕을 남청색·검정·고채도 색으로 칠하지 않는다 — 한지색 위에서만 다홍 끈이 산다. 강조색은 다홍과 금빛 둘뿐.
- 태극 문양·한복 그림·단청 무늬를 넣지 않는다 — 한국적인 맛은 한지 섬유와 매듭 모양에서 나온다.
- 화면 모서리에 버전·제작 표기·장식 라벨을 넣지 않는다 — 글자는 [장면]에 적은 것만.
- 바깥 글꼴·이미지·라이브러리를 불러오지 않는다 — 미리보기 칸에서 막혀 깨진다.
- 매듭 맺힘을 페이드나 사진 교체로 대신하지 않는다 — 구슬이 실제로 움직이고 끈이 휘어 들어가야 한다. 겹쳐 나타나기는 3.2~3.5초 「바꿔 맺기」 한 곳뿐이다.
- 다음 매듭으로 넘어갈 때 매듭을 가운데 한 점으로 줄이거나 가운데에서 퍼뜨리지 않는다 — 맺힌 꽃이 제자리에서 풀려 엉켜야 「풀었던 것이 다시 엉킨다」가 읽힌다.
- 맺힌 국화의 꽃잎 끈을 곧은 선으로, 잎 사이 끈을 바깥으로 불룩하게 두지 않는다 — 원 안의 별처럼 보여 국화가 읽히지 않는다.
- 위쪽 글자를 한 줄에 셋 놓지 않는다 — 폰 세로(폭 390px)에서 제목과 엇갈림 글자가 포개진다. 점수·엇갈림은 첫째 줄, 제목은 둘째 줄.
- 술이 지나가는 화면 아래 띠에 맺힘 동안 글자·단추를 남기지 않는다 — 술이 글자를 덮어 둘 다 지저분해진다.
- 끝 화면을 점수만으로 두지 않는다 — 왜 끝났는지(시간이 다 됨) 한 줄이 있어야 한다.
- 'over' 에 들어간 뒤 입력을 막는 대기 시간을 두지 않는다 — 바로 다시 시작할 수 있어야 한다.
- 이름 있는 상업 게임의 이름·그림을 쓰지 않는다.
사용 방법
필요한 것: claude.ai 계정 — 무료 계정에서도 Claude Opus 5.5 를 고를 수 있습니다
- claude.ai 에서 새 대화를 엽니다.
- 모델 메뉴에서 Claude Opus 5.5 를 고르고, 같은 메뉴의 Effort(답변 깊이)를 High 로 둡니다.
- 복사한 프롬프트를 붙여 넣고 전송합니다. 결과로 나온 HTML 파일을 브라우저로 열면 바로 해 볼 수 있습니다.
추가 요청 예시
결과가 나온 뒤 같은 대화에서 이어서 요청하면 해당 부분만 수정됩니다.
- 끈 색을 쪽빛으로 바꾸고 구슬을 은빛으로 해 줘
- 매듭이 맺힐 때 매듭 이름을 화면 아래에 띄워 줘
- 실마리를 쓸 때 깎이는 시간을 5초로 늘려 줘
미니게임