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

131 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** 할리갈리 30초 규칙 요약 (docs/07 §5). Simple redraws (the real card art lives in index.tsx). */
import type { ReactNode } from 'react';
import type { QuickCard } from '../types';
type F = 'strawberry' | 'banana';
const INK: Record<F, string> = { strawberry: '#e11d48', banana: '#ca8a04' };
/** One fruit centred at (x, y), about 16 units wide. */
function Fruit({ f, x, y }: { f: F; x: number; y: number }) {
if (f === 'strawberry') {
return (
<g transform={`translate(${x - 8} ${y - 8}) scale(0.4)`}>
<path d="M20 38 C9 30 4 20 7.5 13.5 C10.5 8.5 29.5 8.5 32.5 13.5 C36 20 31 30 20 38 Z" fill="#e11d48" stroke="#9f1239" strokeWidth="2" />
<path d="M11 11 L16 9 L20 4 L24 9 L29 11 L23.5 12.5 L20 15 L16.5 12.5 Z" fill="#16a34a" />
</g>
);
}
return (
<g transform={`translate(${x - 8} ${y - 8}) scale(0.4)`}>
<path d="M7 9 C7 27 22 36 36 30 C37 28 36 27 34 27.5 C22 30 13 22 12 8 C11 6 8 6 7 9 Z" fill="#facc15" stroke="#a16207" strokeWidth="2" />
</g>
);
}
const SPOTS: Record<number, [number, number][]> = {
1: [[20, 28]],
2: [[20, 16], [20, 40]],
3: [[11, 14], [20, 28], [29, 42]],
4: [[11, 15], [29, 15], [11, 41], [29, 41]],
5: [[11, 13], [29, 13], [20, 28], [11, 43], [29, 43]],
};
/** A fruit card 40×56 placed at (x, y). */
function Card({ f, n, x, y }: { f: F; n: number; x: number; y: number }) {
return (
<g transform={`translate(${x} ${y})`}>
<rect x={0} y={0} width={40} height={56} rx={5} fill="#fffef8" stroke={INK[f]} strokeWidth={2} />
{SPOTS[n]!.map(([fx, fy], i) => (
<Fruit key={i} f={f} x={fx} y={fy} />
))}
</g>
);
}
function Back({ x, y }: { x: number; y: number }) {
return (
<g transform={`translate(${x} ${y})`}>
<rect x={0} y={0} width={40} height={56} rx={5} fill="#1e3a8a" stroke="#93c5fd" strokeWidth={2} />
<circle cx={20} cy={28} r={7} fill="#fbbf24" />
</g>
);
}
function Bell({ x, y }: { x: number; y: number }) {
return (
<g transform={`translate(${x - 22} ${y - 22}) scale(0.44)`}>
<ellipse cx="50" cy="80" rx="40" ry="9" fill="#78350f" />
<path d="M18 76 C18 50 30 26 50 26 C70 26 82 50 82 76 Z" fill="#fde68a" stroke="#92400e" strokeWidth="3" />
<rect x="43" y="14" width="14" height="13" rx="4" fill="#92400e" />
<circle cx="50" cy="12" r="8" fill="#b91c1c" />
</g>
);
}
function Table({ children }: { children: ReactNode }) {
return (
<svg viewBox="0 0 240 150" width={240} height={150} aria-hidden>
<rect x={0} y={0} width={240} height={150} rx={14} fill="#166534" />
{children}
</svg>
);
}
export const quickStart: QuickCard[] = [
{
pic: (
<Table>
<Back x={20} y={80} />
<path d="M66 108 L88 108" stroke="#fff" strokeWidth={3} />
<path d="M84 102 L92 108 L84 114" fill="none" stroke="#fff" strokeWidth={3} />
<Card f="banana" n={3} x={100} y={80} />
<Card f="strawberry" n={2} x={60} y={12} />
<Card f="banana" n={1} x={140} y={12} />
<Bell x={196} y={110} />
</Table>
),
alt: '뒤집힌 내 카드 더미에서 한 장을 펼쳐 내 앞에 놓는 모습이에요',
title: '차례대로 한 장씩 펼쳐요',
text: '내 차례에 [뒤집기]를 누르면 내 카드가 한 장 펼쳐져요. 각자 앞에 맨 위 카드만 보여요.',
},
{
pic: (
<Table>
<Card f="strawberry" n={2} x={14} y={20} />
<Card f="strawberry" n={3} x={62} y={20} />
<Card f="banana" n={4} x={110} y={20} />
<text x={84} y={108} textAnchor="middle" fontSize={20} fontWeight={800} fill="#fff">
딸기 2+3 = 5
</text>
<Bell x={196} y={52} />
<text x={196} y={110} textAnchor="middle" fontSize={22} fontWeight={900} fill="#fde047">
땡!
</text>
</Table>
),
alt: '딸기 2개 카드와 딸기 3개 카드가 보여서 딸기가 모두 5개예요. 종을 치면 땡!',
title: '딱 5개면 종을 쳐요',
text: '펼쳐진 카드에서 한 과일이 모두 합쳐 딱 5개면 가운데 [종!]을 먼저 눌러요. 맞히면 펼친 카드를 다 가져가요.',
},
{
pic: (
<Table>
<Card f="strawberry" n={2} x={14} y={20} />
<Card f="strawberry" n={3} x={62} y={20} />
<Card f="strawberry" n={1} x={110} y={20} />
<text x={84} y={108} textAnchor="middle" fontSize={20} fontWeight={800} fill="#fff">
딸기 6개
</text>
<Bell x={196} y={52} />
<g stroke="#ef4444" strokeWidth={6} strokeLinecap="round">
<line x1={176} y1={92} x2={216} y2={132} />
<line x1={216} y1={92} x2={176} y2={132} />
</g>
</Table>
),
alt: '딸기가 모두 6개라서 종을 치면 안 된다는 빨간 ✕ 표시예요',
title: '틀리면 카드를 줘요',
text: '4개나 6개일 때 누르면 벌칙으로 카드를 내줘요. 카드를 다 잃으면 탈락이고, 끝까지 남은 사람(시간이 끝나면 카드가 가장 많은 사람)이 이겨요.',
},
];