M9: 컴퓨터 상대 — 게임 22종 컴퓨터 전략, 서버 구동(BotDriver), 연습 방

- packages/shared/src/bots.ts: 컴퓨터 id(bot:<n>:<ulid>)·프로필(컴퓨터 n)·BOT_GAMES
  (도블·할리갈리·그림 맞히기·마피아 제외)
- packages/games/src/bots: 전략 계약(자기 view + 합법 수만), decideBotAction(validate 재검사),
  게임별 <게임>/bot.ts 22개 + 행동 테스트, 전 게임 판 끝까지 돌리는 공통 테스트
- 서버: Room.addBot/removeBot(방장·대기실만, 방은 친구만), RoomManager.createPractice
  (POST /api/rooms {practice:true}), BotDriver(사람 같은 지연, 사람과 같은 창이면 더 천천히,
  재시작 후 다시 예약), 연습 게임은 전적 제외(result_json.practice), 사람이 모두 나가면 무효
- 프로토콜 addBot/removeBot, 문서 03·06 §12·08·09 §8

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-10-06 13:32:28 +09:00
parent c27cb0a11a
commit a3f81ded37
67 changed files with 5113 additions and 18 deletions

View File

@@ -95,3 +95,12 @@ interface Room {
```
- 한 사용자는 동시에 한 방에만 플레이어로 있을 수 있다(다른 방에 들어가면 이전 방 대기실 자리에서 빠짐. 이전 방이 게임 중이면 "진행 중인 게임이 있어요. 그래도 이동할까요?").
- 제한: 서버 전체 방 2,000개, 사용자당 동시에 만든 방 3개.
## 12. 컴퓨터 상대 (혼자 연습)
- 들어가는 곳: 게임 상세와 홈의 [🤖 컴퓨터와 연습하기]. 친구만 방이 열리고, 바로 시작할 수 있을 만큼 컴퓨터가 앉아 있다(예: 오목 1명, 마작 2명, 뱅 3명).
- 대기실: 방장은 첫 빈자리의 [🤖 컴퓨터 넣기]로 넣고, 컴퓨터 자리의 [✕]로 뺀다(대기실에서만). 컴퓨터 이름은 "컴퓨터 1", "컴퓨터 2"…, 아바타는 🤖. 늘 준비 완료이고, 방장은 컴퓨터에게 넘어가지 않는다. 사람이 한 명은 앉아야 시작된다.
- 컴퓨터가 앉은 방은 연습 방이다: 공개로 바꿀 수 없고, 공개 방 목록·빠른 시작에 나오지 않는다. 결과는 남지만 전적(`user_stats`)에는 넣지 않는다. 화면에 "연습 게임이에요. 기록에는 남지 않아요." 표시.
- 컴퓨터가 할 수 있는 게임: 실시간·대화 게임(도블, 할리갈리, 그림 맞히기, 마피아)을 뺀 전부(`packages/shared/src/bots.ts`의 `BOT_GAMES`).
- 움직임: 서버의 `BotDriver`(`apps/server/src/rooms/bots.ts`)가 게임이 컴퓨터를 기다릴 때(차례, 반응 창, 동시 선택, 다음 판 준비) 0.4~1.5초 쉬었다가 한 수를 둔다. 사람과 같은 행동 경로(검사·기록)를 거치고, 서버가 다시 켜져도 이어서 둔다.
- 수 고르기: `packages/games/src/<게임>/bot.ts`. 자기 화면(`view(state, 나)`)과 둘 수 있는 수만 보고 고르므로 남의 패를 볼 수 없다. 강하지 않지만 엉뚱하지 않게(오목은 4를 막고, 오셀로는 귀를 잡고, 카드 게임은 패 세기에 맞게).
- 사람이 모두 나가면 게임은 무효로 끝난다.