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,64 @@
import { expect, test } from 'bun:test';
import { applyAction, setupGame, usersOf } from '../help-kit.test-util';
import { GAMES } from '@bg/games';
import { helpNow } from './help';
const ids = ['A', 'B', 'C'];
const users = usersOf(ids);
const view = (s: unknown, who: string | null) => GAMES['cockroach-poker']!.view(s, who) as any;
const nickOf = (id: string) => users[id]!.nickname;
test('바퀴벌레 포커: 건네기 차례 / 기다림 / 관전', () => {
const { state } = setupGame('cockroach-poker', 3);
const starter = state.round.starter as string;
const other = ids.find((p) => p !== starter)!;
expect(helpNow(view(state, starter), starter, users)).toContain('[건네기]');
const wait = helpNow(view(state, other), other, users);
expect(wait).toContain(`${nickOf(starter)}님이 건넬 카드를 고르는 중`);
expect(wait).toContain('4장 모이면 져요');
expect(helpNow(view(state, null), null, users)).toContain(`${nickOf(starter)}님이 건넬 카드를 고르는 중`);
});
test('바퀴벌레 포커: 받은 사람의 판정 / 몰래 보고 넘기기', () => {
const { state } = setupGame('cockroach-poker', 3);
const starter = state.round.starter as string;
const [to, third] = ids.filter((p) => p !== starter) as [string, string];
const card = state.hands[starter][0] as string;
let s = applyAction('cockroach-poker', state, starter, { type: 'offer', cardId: card, to, claim: 'rat' });
const t = helpNow(view(s, to), to, users);
expect(t).toContain('"이건 쥐야!"');
expect(t).toContain('[⭕ 진짜!]');
expect(t).toContain('[👁 몰래 보고 넘기기]');
expect(helpNow(view(s, starter), starter, users)).toContain('다시 받지 않아요');
expect(helpNow(view(s, null), null, users)).toContain(`${nickOf(to)}님이 진짜인지 고민하는 중`);
s = applyAction('cockroach-poker', s, to, { type: 'peek' });
const p = helpNow(view(s, to), to, users);
expect(p).toContain('몰래 본 카드는');
expect(p).toContain('[넘기기]');
expect(helpNow(view(s, third), third, users)).toContain('나에게 넘어올 수도');
s = applyAction('cockroach-poker', s, to, { type: 'pass', to: third, claim: 'bat' });
const last = helpNow(view(s, third), third, users);
expect(last).toContain('"이건 박쥐야!"');
expect(last).toContain('넘길 사람이 없어요');
});
test('바퀴벌레 포커: 2명은 넘기기 없음, 위험 경고, 게임 끝', () => {
const { state } = setupGame('cockroach-poker', 2);
const starter = state.round.starter as string;
const to = ids.slice(0, 2).find((p) => p !== starter)!;
// 받는 사람 앞마당에 쥐 4장(2명은 5장이면 패배) → 위험 경고.
const rats = ['rat-0', 'rat-1', 'rat-2', 'rat-3', 'rat-4'];
for (const p of ['A', 'B']) state.hands[p] = state.hands[p].filter((c: string) => !rats.includes(c));
state.fronts[to] = rats.slice(0, 4);
state.hands[starter].push('rat-4');
let s = applyAction('cockroach-poker', state, starter, { type: 'offer', cardId: 'rat-4', to, claim: 'rat' });
const t = helpNow(view(s, to), to, users);
expect(t).toContain('2명이 할 때는 몰래 보고 넘기기를 할 수 없어요');
expect(t).toContain('조심! 내 앞마당의 쥐 4장');
s = applyAction('cockroach-poker', s, to, { type: 'call', call: 'false' });
expect(helpNow(view(s, to), to, users)).toContain('내가 졌어요');
expect(helpNow(view(s, starter), starter, users)).toContain('나는 이겼어요');
expect(helpNow(view(s, null), null, users)).toContain(`${nickOf(to)}님이 졌고`);
});