결정 룰렛
룰렛이 당신을 위해 결정하게 하세요, 우유부단함 작별
기록이 없어요 — 돌려보세요!
결정 룰렛이란?
결정 룰렛은 당신의 결정을 돕는 재미있는 도구입니다. 여러 선택지 사이에서 결정하지 못할 때, 모든 선택을 룰렛에 입력하고 회전을 클릭하여 무작위로 결정하게 하세요.
일반적인 사용 사례:
- 오늘 뭐 먹을까? 레스토랑 선택을 룰렛에 추가
- 주말에 어디 갈까? 목적지를 룰렛에 추가
- 무슨 영화 볼까? 영화 선택을 룰렛에 추가
- 팀 활동 선택, 공정한 결정
공정성을 높이려면 선택지를 같은 기준으로 입력하고 중복 항목을 피하는 것이 좋습니다. 업무 배정이나 추첨에 사용할 때는 결과 기록과 참여자 동의를 함께 남기면 분쟁을 줄일 수 있습니다.
사용 방법
사용 방법
- 입력 상자에 옵션 이름을 입력하고 Enter를 누르거나 추가를 클릭하세요
- 옵션을 여러 개 추가할 수 있습니다 (최대 15개, 각 옵션 최대 20자)
- 중앙의 'SPIN' 버튼을 클릭하면 휠이 회전하기 시작합니다
- 휠이 멈출 때까지 기다리면 무작위로 선택된 결과가 표시됩니다
공정성 팁
- 옵션을 짧고 비슷한 길이로 작성해 휠이 멈추기 전에 누구나 쉽게 읽을 수 있게 하세요.
- 중요한 결정에서는 회전 전에 옵션 목록을 확정하고, 불리한 결과가 나온 후에는 항목을 바꾸지 마세요.
활용 사례
기술 원리
룰렛은 결정적 랜덤 선택과 결합된 Canvas 2D 드로잉입니다. 각 조각은 ctx.beginPath(); ctx.moveTo(cx, cy); ctx.arc(cx, cy, r, startAngle, endAngle); ctx.fill()로 렌더링됩니다. N개의 동일한 옵션은 각각 2π/N 라디안의 호를 차지합니다. 15개 조각은 각각 24도 호이며, 이것이 입력이 15개로 제한되는 이유이기도 합니다(레이블의 가독성을 유지하기 위해). 당첨 조각은 애니메이션 전에 결정됩니다. crypto.getRandomValues(new Uint32Array(1))[0]으로 32비트 부호 없는 정수를 생성하고 N으로 나눈 나머지가 답입니다. 그런 다음 애니메이션은 목표 회전값 fullSpins × 2π + (2π − winnerIndex × sliceAngle − sliceAngle/2)를 계산하여 캔버스 상단의 포인터가 선택된 조각의 중앙을 가리키게 하고, easeOutCubic f(t) = 1 − (1−t)^3 또는 물리적 룰렛이 느려지는 것을 모방하는 미세한 오버슈트를 위한 easeOutBack 같은 이징 커브를 사용하여 requestAnimationFrame 내에서 트위닝합니다. crypto.getRandomValues는 Web Crypto API에 명시된 Web Crypto CSPRNG로, OS 엔트로피 풀에서 시드되므로 Math.random과 달리 페이지 상태를 읽어 예측할 수 없습니다. 가중치 변형은 길이 N의 누적 확률 배열을 만들고 O(log N)로 이진 탐색합니다. 출력은 전적으로 시각적이고 일시적입니다. 아무것도 기록되지 않으므로 감사 추적(타임스탬프, 옵션 목록, 스크린샷)은 페이지를 새로고침하기 전에 외부에서 캡처해야 합니다.
- Canvas 렌더링: 각 조각은 sliceAngle = 2π / N인 ctx.arc(cx, cy, r, startAngle, endAngle). 15개 옵션은 조각당 24도 호이며, 이것이 실용적인 가독성 상한선입니다.
- 당첨 선택은 crypto.getRandomValues(new Uint32Array(1))[0] % N을 사용. Web Crypto CSPRNG, OS 엔트로피에서 시드. 공정한 일회성 추첨에는 적합하지만 재현 가능한 추첨에는 부적합(감사 추적 없음).
- 애니메이션은 디스플레이 주사율(보통 60Hz)에서 requestAnimationFrame으로 실행. easeOutCubic f(t) = 1 − (1−t)^3 또는 미세한 오버슈트를 위한 easeOutBack 사용. 커브는 장식적이며 당첨자는 이미 결정되어 있습니다.
- 최종 회전값은 targetRotation = fullSpins × 2π + (2π − winnerIndex × sliceAngle − sliceAngle/2)로, 상단 포인터가 조각 가장자리가 아닌 중앙에 위치합니다.
- 가중치 옵션 모드는 가중치의 접두 합 배열을 만들고 이진 탐색으로 균일 난수를 조각에 매핑합니다(O(log N)). 역 CDF 샘플링과 동등합니다.
- N ≤ 15이고 추첨 범위가 2^32 값일 때 모듈로 바이어스는 무시할 수 있습니다(바이어스 ≈ N / (2 × 2^32) ≈ 1.7×10^-9). 따라서 기각 샘플링 루프가 필요하지 않습니다.
- 각 회전은 독립 동일 분포(i.i.d.)입니다. 연속 회전이 같은 옵션을 반복할 수 있으며 이는 올바른 균등 동작이지 버그가 아닙니다. 회전 간 중복 제거에는 외부 기록이 필요합니다.
예시
점심 메뉴 결정
선택지: 피자, 스시, 버거, 타코, 샐러드 → 돌리기 → 결과: 스시팀 액티비티
선택지: 볼링, 노래방, 방탈출, 미니 골프 → 돌리기 → 결과: 방탈출영화의 밤
선택지: 액션, 코미디, 호러, 로맨스, SF → 돌리기 → 결과: 코미디자주 묻는 질문
룰렛 회전이 정말로 무작위인가요?
네. 선택된 구간은 crypto.getRandomValues로 결정된 후 룰렛이 해당 구간에 멈추도록 애니메이션됩니다. 시각적인 회전은 연출일 뿐이며 결과는 미리 정해져 있습니다. 각 회전은 이전 회전과 독립적입니다.
모든 구간의 확률이 동일한가요?
네. 각 옵션은 동일한 크기의 조각을 차지하며, 각 조각의 확률도 동일합니다. 가중치를 적용하거나 편향된 모드는 없으며 모든 옵션의 선택 확률이 같습니다.
회전 애니메이션이 결과에 영향을 주나요?
아니요. 애니메이션은 시각적 연출일 뿐, 결과가 먼저 계산된 후 룰렛이 해당 결과를 보여주기 위해 회전합니다. 애니메이션을 일찍 멈춰도 선택된 구간은 동일합니다.
세션 간에 룰렛을 저장할 수 있나요?
아니요. 옵션은 현재 세션 동안만 유지됩니다. 탭을 닫거나 새로고침하면 목록이 사라집니다. 다시 사용하려면 닫기 전에 옵션을 복사해 두세요.
중요한 결정을 내리는 데 사용해도 될까요?
어떤 옵션을 선택해도 무방하고 무작위성이 시각적으로 드러나서 서운함을 줄여주는 가벼운 그룹 결정(점심 메뉴, 발표 순서, 드래프트 순번)에 사용하세요. 옵션 간 결과 차이가 큰 결정은 룰렛에 맡기지 마세요. 룰렛은 트레이드오프를 따져볼 수 없습니다.
왜 가끔 같은 옵션이 연속으로 두 번 선택되나요?
각 회전은 독립적이기 때문입니다. 옵션이 3개일 때 같은 옵션이 두 번 연속 선택될 확률은 1/3 ≈ 33%이며, 옵션이 10개일 때는 10%입니다. 반복이 이상해 보일 수 있지만 진짜 무작위 선택에서는 수학적으로 자연스러운 결과입니다.
옵션 목록이 업로드되나요?
아니요. 룰렛은 전적으로 브라우저에서 실행됩니다. 옵션은 사용자가 동의한 경우에만 로컬에 저장되며, 어떤 정보도 외부로 전송되지 않습니다.