/**
* 도블 그림 57종 (docs/games/dobble.md §3.2) — all drawn here as simple SVG in a 100×100 box.
* Every picture has its own silhouette with a dark outline, so colour is only a secondary cue (colour-blind friendly).
* Index = icon id (same order as SYMBOL_NAMES in @bg/games/dobble).
*/
import type { ReactNode } from 'react';
const O = '#1f2937';
/** Outline props for filled shapes. */
const L = { stroke: O, strokeWidth: 3.5, strokeLinejoin: 'round', strokeLinecap: 'round' } as const;
/** Thick stroked lines (no fill). */
const W = (color: string, w = 6) => ({ stroke: color, strokeWidth: w, strokeLinecap: 'round', strokeLinejoin: 'round', fill: 'none' }) as const;
const rays = (n: number, r1: number, r2: number, cx = 50, cy = 50, a0 = 0) =>
Array.from({ length: n }, (_, i) => {
const a = a0 + (i * 2 * Math.PI) / n;
return `M${(cx + Math.cos(a) * r1).toFixed(1)} ${(cy + Math.sin(a) * r1).toFixed(1)} L${(cx + Math.cos(a) * r2).toFixed(1)} ${(cy + Math.sin(a) * r2).toFixed(1)}`;
}).join(' ');
const starPts = (n: number, ro: number, ri: number, cx = 50, cy = 52) =>
Array.from({ length: n * 2 }, (_, i) => {
const a = -Math.PI / 2 + (i * Math.PI) / n;
const r = i % 2 ? ri : ro;
return `${(cx + Math.cos(a) * r).toFixed(1)},${(cy + Math.sin(a) * r).toFixed(1)}`;
}).join(' ');
/** Korean names, same order as SYMBOL_NAMES in @bg/games/dobble (kept here so the screen does not pull in the rules module; a test checks they match). */
export const ICON_NAMES = [
'사과', '해', '달', '별', '하트', '물방울', '불꽃', '눈송이', '번개', '구름',
'나무', '꽃', '나뭇잎', '선인장', '버섯', '당근', '레몬', '체리', '고양이', '강아지',
'물고기', '새', '거북이', '무당벌레', '거미', '공룡', '토끼', '펭귄', '열쇠', '자물쇠',
'시계', '전구', '연필', '가위', '안경', '우산', '모자', '왕관', '종', '닻',
'자전거', '자동차', '로켓', '배', '공', '주사위', '음표', '카메라', '집', '성',
'선물상자', '촛불', '망치', '느낌표', '물음표', '눈사람', '무지개',
];
export const ICONS: (() => ReactNode)[] = [
// 0 사과
() => (
<>
>
),
// 1 해
() => (
<>
>
),
// 2 달
() => ,
// 3 별
() => ,
// 4 하트
() => ,
// 5 물방울
() => (
<>
>
),
// 6 불꽃
() => (
<>
>
),
// 7 눈송이
() => (
<>
{
const a = Math.PI / 2 + (i * Math.PI) / 3;
const bx = 50 + Math.cos(a) * 26;
const by = 50 + Math.sin(a) * 26;
const p = (d: number) => `${(bx + Math.cos(a + d) * 12).toFixed(1)} ${(by + Math.sin(a + d) * 12).toFixed(1)}`;
return `M${p(0.9)} L${bx.toFixed(1)} ${by.toFixed(1)} L${p(-0.9)}`;
}).join(' ')} {...W('#0284c7', 5)} />
>
),
// 8 번개
() => ,
// 9 구름
() => ,
// 10 나무 (pine)
() => (
<>
>
),
// 11 꽃
() => (
<>
{[0, 1, 2, 3, 4].map((i) => {
const a = -Math.PI / 2 + (i * 2 * Math.PI) / 5;
return ;
})}
>
),
// 12 나뭇잎
() => (
<>
>
),
// 13 선인장
() => (
<>
>
),
// 14 버섯
() => (
<>
>
),
// 15 당근
() => (
<>
>
),
// 16 레몬
() => (
<>
>
),
// 17 체리
() => (
<>
>
),
// 18 고양이
() => (
<>
>
),
// 19 강아지
() => (
<>
>
),
// 20 물고기
() => (
<>
>
),
// 21 새
() => (
<>
>
),
// 22 거북이
() => (
<>
>
),
// 23 무당벌레
() => (
<>
>
),
// 24 거미
() => (
<>
>
),
// 25 공룡
() => (
),
// 26 토끼
() => (
<>
>
),
// 27 펭귄
() => (
<>
>
),
// 28 열쇠
() => (
<>
>
),
// 29 자물쇠
() => (
<>
>
),
// 30 시계
() => (
<>
>
),
// 31 전구
() => (
<>
>
),
// 32 연필
() => (
),
// 33 가위
() => (
<>
>
),
// 34 안경
() => (
<>
>
),
// 35 우산
() => (
<>
>
),
// 36 모자 (top hat)
() => (
<>
>
),
// 37 왕관
() => (
<>
>
),
// 38 종
() => (
<>
>
),
// 39 닻
() => (
<>
>
),
// 40 자전거
() => (
<>
>
),
// 41 자동차
() => (
<>
>
),
// 42 로켓
() => (
<>
>
),
// 43 배 (sailboat)
() => (
<>
>
),
// 44 공 (soccer ball)
() => (
<>
i % 2 === 0).join(' ')} fill={O} />
{[0, 1, 2, 3, 4].map((i) => {
const a = -Math.PI / 2 + (i * 2 * Math.PI) / 5;
return ;
})}
>
),
// 45 주사위
() => (
<>
{[
[30, 30],
[70, 30],
[50, 50],
[30, 70],
[70, 70],
].map(([x, y]) => (
))}
>
),
// 46 음표
() => (
<>
>
),
// 47 카메라
() => (
<>
>
),
// 48 집
() => (
<>
>
),
// 49 성
() => (
<>
>
),
// 50 선물상자
() => (
<>
>
),
// 51 촛불
() => (
<>
>
),
// 52 망치
() => (
),
// 53 느낌표
() => (
<>
>
),
// 54 물음표
() => (
<>
>
),
// 55 눈사람
() => (
<>
>
),
// 56 무지개
() => (
<>
{['#ef4444', '#f97316', '#facc15', '#22c55e', '#3b82f6', '#8b5cf6'].map((c, i) => (
))}
>
),
];
/** One icon in its own 100×100 SVG. */
export function SymbolArt({ art, className }: { art: number; className?: string }) {
const draw = ICONS[art];
return (
);
}