M9: 게임 26종 30초 요약 카드·[?] 지금 할 수 있는 것 내용

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-10-06 13:35:21 +09:00
parent 32e3e89d8d
commit 68edd9b434
102 changed files with 6555 additions and 1 deletions

View File

@@ -0,0 +1,53 @@
/** 라스베가스 주사위 [?] "지금 할 수 있는 것" (docs/07 §5). Pure: only reads the client view. */
import type { LasVegasChoice, LasVegasView } from '@bg/games/las-vegas';
import type { PublicUser } from '@bg/shared/lite';
const STANDING: Record<LasVegasChoice['standing'], (c: LasVegasChoice) => string> = {
first: (c) => `1등${c.note !== null ? `(${c.note}점 지폐)` : ''}`,
award: (c) => (c.note !== null ? `${c.note}점 지폐` : '지폐 받음'),
tie: () => '동점이라 꽝',
none: (c) => (c.own === 0 ? '흰 주사위만 놓임' : '받을 지폐 없음'),
};
const choiceText = (c: LasVegasChoice) => `${c.value}번에 ${c.own + c.neutral}개 → ${STANDING[c.standing](c)}`;
export function helpNow(v: LasVegasView, me: string | null, players: Record<string, PublicUser>): string {
if (v.phase === 'finished' || !v.current) return `게임이 끝났어요. ${v.result?.summary ?? ''}`.trim() + '\n결과 창에서 [한 판 더]를 누르면 다시 할 수 있어요.';
const round = `${v.round}/${v.rounds}라운드`;
const who = `${players[v.current]?.nickname ?? '다른 사람'}님`;
const rule = '라운드가 끝나면 카지노마다 주사위가 가장 많은 사람부터 큰 지폐를 가져가요. 개수가 같은 사람끼리는 모두 꽝이에요.';
const seated = !!me && v.seats.includes(me);
if (!seated) {
const doing = v.phase === 'roll' ? '주사위를 굴릴 차례예요.' : '나온 숫자 중 하나를 골라 카지노에 놓는 중이에요.';
return `${who}이 ${doing} (${round})\n${rule}`;
}
if (v.conceded.includes(me!)) return `나는 기권해서 지금은 구경만 할 수 있어요. ${who} 차례예요.`;
const hand = v.hand[me!];
const left = hand ? hand.own + hand.neutral : 0;
const mine = v.money[me!];
const score = mine && mine.total !== null ? `지금까지 내 점수는 ${mine.total}점(지폐 ${mine.count}장)이에요.` : '';
if (v.current !== me) {
const doing = v.phase === 'roll' ? '주사위를 굴릴 차례예요.' : '놓을 숫자를 고르는 중이에요.';
const lines = [`${who}이 ${doing} 기다려 주세요. (${round})`];
lines.push(left > 0 ? `내 주사위는 ${left}개 남았어요${hand!.neutral > 0 ? `(흰 주사위 ${hand!.neutral}개 포함)` : ''}.` : '내 주사위는 이번 라운드에 다 놓았어요. 다른 사람이 다 놓을 때까지 기다려요.');
if (score) lines.push(score);
return lines.join('\n');
}
// My turn.
if (v.phase === 'roll') {
const lines = [`내 차례예요(${round}). [🎲 주사위 굴리기]를 누르면 남은 주사위 ${left}개를 모두 굴려요.`];
lines.push('굴린 뒤 숫자 하나를 고르면, 그 숫자가 나온 주사위를 모두 같은 번호 카지노에 놓아요.');
if (v.houseRoll && v.houseRoll.round === v.round && hand?.own === 8) lines.push(`이번 라운드 시작에 남는 흰 주사위가 ${v.houseRoll.values.map((x) => `${x}번`).join(', ')} 카지노에 놓였어요.`);
if (score) lines.push(score);
return lines.join('\n');
}
const lines = [`내 차례예요(${round}). 나온 숫자(또는 같은 번호 카지노)를 누르면 미리 보기가 나와요. 그다음 [… 카지노에 …개 놓기] 버튼을 눌러 확정해요.`];
lines.push('고른 숫자의 주사위는 한꺼번에 모두 놓여요. 일부만 놓을 수는 없어요.');
if (v.choices.length) lines.push(`지금 상황에서 놓으면: ${v.choices.map(choiceText).join(' · ')}`);
if (v.choices.some((c) => c.standing === 'tie')) lines.push('동점이 되는 곳은 그대로 끝나면 같은 개수인 사람 모두 아무것도 못 받아요.');
return lines.join('\n');
}