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

88 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** 주사위 땅따먹기 30초 규칙 요약 (docs/07 §5). */
import type { ReactNode } from 'react';
import type { QuickCard } from '../types';
const PIPS: Record<number, [number, number][]> = {
1: [[50, 50]],
2: [[28, 28], [72, 72]],
3: [[26, 26], [50, 50], [74, 74]],
4: [[28, 28], [72, 28], [28, 72], [72, 72]],
5: [[26, 26], [74, 26], [50, 50], [26, 74], [74, 74]],
6: [[28, 24], [72, 24], [28, 50], [72, 50], [28, 76], [72, 76]],
};
function Die({ value }: { value: number }) {
return (
<svg viewBox="0 0 100 100" width={56} height={56} aria-hidden>
<rect x={4} y={4} width={92} height={92} rx={18} fill="#fffdf8" stroke="#9ca3af" strokeWidth={5} />
{PIPS[value]!.map(([x, y], i) => (
<circle key={i} cx={x} cy={y} r={10} fill="#1c1e21" />
))}
</svg>
);
}
/** A city square like on the board: colour band, name, and a line below. */
function Tile({ name, color, children, owner }: { name: string; color: string; children: ReactNode; owner?: string }) {
return (
<div style={{ width: 96, borderRadius: 10, overflow: 'hidden', border: `3px solid ${owner ?? '#d1d5db'}`, background: '#fff', textAlign: 'center' }}>
<div style={{ background: color, height: 16 }} />
<div style={{ fontWeight: 800, fontSize: '1rem', padding: '4px 0 0', color: '#111' }}>{name}</div>
<div style={{ fontSize: '0.95rem', padding: '2px 4px 6px', color: '#111' }}>{children}</div>
</div>
);
}
const row = { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10 } as const;
export const quickStart: QuickCard[] = [
{
pic: (
<div style={row} aria-hidden>
<Die value={3} />
<Die value={5} />
<span style={{ fontSize: 28 }}>➜</span>
<Tile name="방콕" color="#38bdf8">
<b>10P</b>에 사기
</Tile>
</div>
),
alt: '주사위 3과 5를 굴려 방콕 칸에 도착하고, 10P에 살 수 있어요',
title: '굴리고 땅을 사요',
text: '주사위 2개를 굴린 만큼 판을 돌아요. 주인 없는 땅에 서면 [사기]로 내 땅으로 만들 수 있어요.',
},
{
pic: (
<div style={row} aria-hidden>
<Tile name="로마" color="#db2777" owner="#dc2626">
<span style={{ fontSize: 22 }}>🏠🏢🏨</span>
</Tile>
<div style={{ textAlign: 'center', fontWeight: 800, color: '#b91c1c' }}>
<div style={{ fontSize: 30 }}>🚶</div>
통행료
<br />
40P
</div>
</div>
),
alt: '별장·빌딩·호텔을 지은 로마 칸에 다른 사람이 와서 통행료 40P를 내요',
title: '짓고 통행료 받기',
text: '내 땅에 다시 오면 별장→빌딩→호텔을 한 단계씩 지어요. 남이 내 땅에 서면 통행료를 받고, 건물이 클수록 비싸요.',
},
{
pic: (
<div style={{ ...row, gap: 16 }} aria-hidden>
<div style={{ textAlign: 'center', fontWeight: 700 }}>
<div style={{ fontSize: 44 }}>🏝️</div>무인도
</div>
<div style={{ textAlign: 'center', fontWeight: 700 }}>
<div style={{ fontSize: 44 }}>🏆</div>총자산 1등
</div>
</div>
),
alt: '무인도 섬과 총자산 1등 트로피 그림',
title: '총자산이 많으면 이겨요',
text: '무인도에선 몇 차례 쉬어요(더블이면 바로 탈출). 라운드가 다 끝날 때 총자산(포인트+땅+건물)이 가장 많거나, 남이 모두 파산하면 이겨요.',
},
];