/** 장기 30초 규칙 요약 (docs/07 §5). */ import type { ReactNode } from 'react'; import type { QuickCard } from '../types'; type Side = 'cho' | 'han'; const INK: Record = { cho: '#1d4ed8', han: '#c0262d' }; function octagon(cx: number, cy: number, r: number): string { return Array.from({ length: 8 }, (_, i) => { const a = Math.PI / 8 + (i * Math.PI) / 4; return `${(cx + r * Math.cos(a)).toFixed(3)},${(cy + r * Math.sin(a)).toFixed(3)}`; }).join(' '); } /** Octagonal piece with its hanja, blue for 초 and red for 한. */ function Piece({ ch, side, x, y, r = 0.4 }: { ch: string; side: Side; x: number; y: number; r?: number }) { return ( {ch} ); } /** Wooden board of w×h line crossings; `palace` draws the X of a 3×3 palace whose top-left crossing is given. */ function Board({ w, h, size, palace, children }: { w: number; h: number; size: number; palace?: [number, number]; children: ReactNode }) { const pad = 0.55; const vw = w - 1 + 2 * pad; const vh = h - 1 + 2 * pad; const scale = size / Math.max(vw, vh); return ( {Array.from({ length: w }, (_, x) => ( ))} {Array.from({ length: h }, (_, y) => ( ))} {palace && ( <> )} {children} ); } const Dot = ({ x, y }: { x: number; y: number }) => ; const Cross = ({ x, y }: { x: number; y: number }) => ( ); export const quickStart: QuickCard[] = [ { pic: ( ), alt: '파란 차가 궁성 안의 빨간 궁을 곧게 겨누고 있어요(장군)', title: '상대 궁을 몰아요', text: '초(파랑)가 먼저 두고 번갈아 한 수씩 둬요. 상대 궁이 어디로 피해도 잡히게 만들면(외통) 이겨요.', }, { pic: ( {[[0, 1], [4, 1], [0, 3], [4, 3], [1, 4], [3, 4]].map(([x, y]) => ( ))} ), alt: '가운데 마 둘레에 갈 수 있는 곳이 초록 점으로, 바로 위가 막힌 쪽은 빨간 ✕로 보여요', title: '누르면 갈 곳이 보여요', text: '기물을 누르면 갈 수 있는 곳에 초록 점이 찍혀요. 기물은 칸이 아니라 선이 만나는 점에 놓여요. 마·상은 바로 앞(멱)이 막히면 못 가요.', }, { pic: ( ), alt: '포가 기물 하나를 뛰어넘어 그 너머 점으로 가는 모습이에요', title: '포는 넘어서 가요', text: '포는 꼭 기물 하나를 뛰어넘어서만 움직여요. 장군을 받으면 다른 수보다 먼저 궁을 피하거나 막아야 해요.', }, ];