Files
joke-app/apps/web/src/games/catchmind/quick.tsx
2026-10-06 13:35:21 +09:00

131 lines
4.8 KiB
TypeScript

/** 그림 맞히기 30초 규칙 요약 (docs/07 §5). */
import type { ReactNode } from 'react';
import type { QuickCard } from '../types';
function Pic({ children }: { children: ReactNode }) {
return (
<svg viewBox="0 0 250 150" width={250} height={150} aria-hidden>
{children}
</svg>
);
}
/** White drawing paper with a simple cat doodle. */
function Paper({ x, y, w = 120, blank = false }: { x: number; y: number; w?: number; blank?: boolean }) {
const k = w / 120;
return (
<g transform={`translate(${x} ${y}) scale(${k})`}>
<rect x={0} y={0} width={120} height={110} rx={8} fill="#fff" stroke="#94a3b8" strokeWidth={2} />
{!blank && <Cat />}
</g>
);
}
function Cat() {
return (
<>
<g fill="none" stroke="#1f2937" strokeWidth={3} strokeLinecap="round" strokeLinejoin="round">
<circle cx={60} cy={62} r={28} />
<path d="M38 44 L36 22 L52 36" />
<path d="M82 44 L84 22 L68 36" />
<path d="M30 66 L12 62 M30 72 L12 76 M90 66 L108 62 M90 72 L108 76" />
<path d="M54 72 Q60 78 66 72" />
</g>
<circle cx={50} cy={56} r={3.5} fill="#1f2937" />
<circle cx={70} cy={56} r={3.5} fill="#1f2937" />
</>
);
}
function Bubble({ x, y, text, ok }: { x: number; y: number; text: string; ok?: boolean }) {
return (
<g>
<rect x={x} y={y} width={92} height={30} rx={15} fill={ok ? '#dcfce7' : '#f1f5f9'} stroke={ok ? '#16a34a' : '#94a3b8'} strokeWidth={2} />
<text x={x + 46} y={y + 20} textAnchor="middle" fontSize={14} fontWeight={700} fill="#1f2937">
{text}
</text>
</g>
);
}
export const quickStart: QuickCard[] = [
{
pic: (
<Pic>
<Paper x={8} y={20} />
<text x={118} y={36} fontSize={26} aria-hidden>
🖍
</text>
<Bubble x={150} y={22} text="강아지?" />
<Bubble x={150} y={62} text="호랑이?" />
<Bubble x={150} y={102} text="고양이!" ok />
</Pic>
),
alt: '그림판에 고양이 그림이 있고, 옆에 사람들이 정답을 써 보낸 말풍선이 있어요',
title: '한 명이 그리고 모두 맞혀요',
text: '차례대로 한 사람이 단어를 그림으로 그리고, 나머지는 그림을 보고 정답을 채팅 칸에 써서 맞혀요.',
},
{
pic: (
<Pic>
<Paper x={20} y={20} blank />
<text x={80} y={70} textAnchor="middle" fontSize={30} fontWeight={800} fill="#475569" opacity={0.85}>
고양이
</text>
<g stroke="#dc2626" strokeWidth={7} strokeLinecap="round">
<line x1={40} y1={34} x2={120} y2={114} />
<line x1={120} y1={34} x2={40} y2={114} />
</g>
<g transform="translate(160 28)">
{['○', '○', '○'].map((c, i) => (
<g key={i}>
<rect x={i * 28} y={0} width={24} height={30} rx={5} fill="#f1f5f9" stroke="#94a3b8" />
<text x={i * 28 + 12} y={21} textAnchor="middle" fontSize={15} fill="#334155">
{c}
</text>
</g>
))}
{['ㄱ', 'ㅇ', 'ㅇ'].map((c, i) => (
<g key={i}>
<rect x={i * 28} y={50} width={24} height={30} rx={5} fill="#f1f5f9" stroke="#94a3b8" />
<text x={i * 28 + 12} y={71} textAnchor="middle" fontSize={15} fontWeight={700} fill="#334155">
{c}
</text>
</g>
))}
</g>
</Pic>
),
alt: '그림판에 글자를 쓴 것에 빨간 ✕ 표시가 있고, 옆에 글자 수와 첫소리 힌트 칸이 있어요',
title: '글자는 쓰면 안 돼요',
text: '그리는 사람만 단어를 보고, 글자나 숫자 없이 그림으로만 설명해요. 방 설정에 따라 글자 수·첫소리 힌트가 보여요.',
},
{
pic: (
<Pic>
{[
['1등', '+10', 48],
['2등', '+8', 125],
['3등', '+6', 202],
].map(([a, b, x]) => (
<g key={a as string}>
<circle cx={x as number} cy={60} r={32} fill="#fef3c7" stroke="#d97706" strokeWidth={3} />
<text x={x as number} y={55} textAnchor="middle" fontSize={15} fontWeight={700} fill="#92400e">
{a}
</text>
<text x={x as number} y={77} textAnchor="middle" fontSize={20} fontWeight={800} fill="#92400e">
{b}
</text>
</g>
))}
<text x={125} y={130} textAnchor="middle" fontSize={15} fontWeight={700} fill="currentColor">
빨리 맞힐수록 점수가 커요
</text>
</Pic>
),
alt: '먼저 맞힌 순서대로 1등 10점, 2등 8점, 3등 6점을 받는 모습이에요',
title: '빨리 맞히면 점수가 커요',
text: '먼저 맞힐수록 점수를 많이 받고, 누가 맞히면 그린 사람도 점수를 받아요. 모두 다 그린 뒤 점수가 가장 높으면 우승!',
},
];