# BOT BRAWL 해커톤 봇 제작 가이드

## 목표

브라우저에서 JavaScript 봇을 제출하면 서버가 `decide(input)` 함수를 호출해 경기 행동을 결정합니다. 봇은 매 턴 현재 공개 정보만 보고 정해진 action 객체를 반환해야 합니다.

## 공통 제출 형식

```js
export function decide(input) {
  // input.game: "indian-poker" 또는 "alkkagi"
  // input.playerId: "A" 또는 "B"
  // input.turn: 현재 턴 번호
  // input.state: 게임별 공개 상태
  return { type: "CALL" };
}
```

허용되는 전역 객체는 `Math`, `JSON`, `structuredClone`, `console.log` 정도입니다. 상태 객체를 바꿔도 실제 경기 상태에는 반영되지 않습니다.

## 보안 / 페어플레이 규칙

- 외부 네트워크 호출 금지: `fetch`, `XMLHttpRequest`, `WebSocket`, `EventSource` 사용 금지.
- 런타임 탈출 금지: `eval`, `Function`, `import`, `require`, `process`, `globalThis`, `constructor.constructor` 사용 금지.
- 파일/환경변수/서버 정보 접근 금지.
- 무한 루프, 과도한 계산, 의도적 timeout 유발 금지.
- 상대 봇 소스, 서버 secret, 내부 API 탐색 같은 침입 시도 금지.
- 위반 봇은 경기 중 기권 처리되거나 대회에서 제외될 수 있습니다.

## 인디언 포커

상대 카드만 보이는 1:1 베팅 게임입니다. 내 카드는 볼 수 없습니다. 각 라운드마다 ante가 걸리고, CALL/RAISE/FOLD 중 하나를 반환합니다.

입력 예시:

```js
input.state = {
  round: 1,
  visibleOpponentCard: 8,
  myChips: 18,
  opponentChips: 20,
  pot: 2,
  toCall: 1,
  maxRaise: 3
};
```

반환 형식:

```js
return { type: "CALL" };
return { type: "RAISE", amount: 2 }; // amount는 maxRaise 이하
return { type: "FOLD" };
```

기본 예제:

```js
export function decide(input) {
  const { visibleOpponentCard, toCall, maxRaise, myChips } = input.state;

  if (toCall > 0 && visibleOpponentCard >= 8) {
    return { type: "FOLD" };
  }

  if (visibleOpponentCard <= 3 && maxRaise > 0 && myChips > toCall + 2) {
    return { type: "RAISE", amount: Math.min(2, maxRaise) };
  }

  return { type: "CALL" };
}
```

## 알까기

내 알 하나를 골라 각도와 힘을 반환합니다. 엔진이 이동, 충돌, 장외 판정을 계산합니다.

입력 예시:

```js
input.state = {
  turn: 4,
  myStones: [{ id: "A1", x: 30, y: 50, alive: true }],
  opponentStones: [{ id: "B1", x: 70, y: 50, alive: true }]
};
```

반환 형식:

```js
return { stoneId: "A1", angle: 0, power: 0.8 };
```

- `stoneId`: 살아있는 내 알 id
- `angle`: 0 이상 360 미만, 오른쪽이 0도
- `power`: 0 이상 1 이하

기본 예제:

```js
export function decide(input) {
  const stone = input.state.myStones[0];
  const target = input.state.opponentStones[0];
  const angle = Math.atan2(target.y - stone.y, target.x - stone.x) * 180 / Math.PI;

  return {
    stoneId: stone.id,
    angle: angle < 0 ? angle + 360 : angle,
    power: 0.9
  };
}
```
