Metadata-Version: 2.4
Name: noprune
Version: 0.1.0
Summary: Python client for noprune chess bot platform - easily create custom chess engines
Project-URL: Homepage, https://noprune.org
Project-URL: Documentation, https://github.com/noprune/noprune/tree/main/clients/python
Project-URL: Repository, https://github.com/noprune/noprune
Project-URL: Issues, https://github.com/noprune/noprune/issues
Author-email: noprune <contact@noprune.org>
License: MIT
License-File: LICENSE
Keywords: ai,bot,chess,engine,game,websocket
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Games/Entertainment :: Board Games
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: python-chess>=1.10.0
Requires-Dist: websockets>=12.0
Description-Content-Type: text/markdown

# noprune

Python client for the noprune chess bot platform.

## Installation

```bash
pip install noprune
```

Or for development:

```bash
pip install -e clients/python
```

## Quick Start

가장 간단한 봇:

```python
from noprune import Bot
import random

@Bot(system_id="your-system-id", secret="your-secret")
def my_bot(board) -> str:
    """board는 python-chess의 Board 객체"""
    return random.choice(list(board.legal_moves)).uci()

my_bot.run()
```

## Game Actions

기권, 무승부 제안 등:

```python
from noprune import Bot, Action

@Bot(system_id="...", secret="...")
def my_bot(board) -> str | Action:
    # 불리하면 기권
    if is_losing_badly(board):
        return Action.RESIGN

    # 무승부 제안
    if board.halfmove_clock >= 50:
        return Action.OFFER_DRAW

    return calculate_best_move(board)
```

## Advanced Usage

클래스를 상속해서 더 세밀한 제어:

```python
from noprune import Bot, GameState, Action

class MyBot(Bot):
    def on_game_start(self, game: GameState):
        print(f"게임 시작! 상대: {game.opponent}, 내 색: {game.color}")
        self.move_count = 0

    def on_move(self, game: GameState, move: str, is_my_move: bool):
        print(f"{'나' if is_my_move else '상대'}: {move}")

    def on_game_end(self, game: GameState, result: str, reason: str):
        print(f"게임 종료: {result} ({reason})")

    def on_draw_offer(self, game: GameState) -> bool:
        """상대가 무승부 제안 시. True=수락"""
        return len(game.moves) > 100

    def think(self, board) -> str | Action:
        self.move_count += 1
        # 여기서 수 계산
        return "e2e4"

bot = MyBot(system_id="...", secret="...")
bot.run()
```

## GameState

```python
@dataclass
class GameState:
    game_id: str           # 게임 ID
    board: chess.Board     # python-chess Board
    color: str             # "white" | "black"
    opponent: str          # 상대 이름
    moves: list[str]       # UCI 수 목록
    my_time_ms: int        # 내 남은 시간 (ms)
    opponent_time_ms: int  # 상대 남은 시간 (ms)
```

## Action

```python
Action.RESIGN       # 기권
Action.OFFER_DRAW   # 무승부 제안
Action.move("e2e4") # 수 두기 (문자열 반환과 동일)
```

## Examples

`examples/` 디렉토리 참고:

- `random_bot.py` - 가장 간단한 예제
- `stockfish_bot.py` - Stockfish 엔진 연동
- `minimax_bot.py` - 커스텀 미니맥스 알고리즘

### 실행 방법

```bash
# 환경변수 설정
export SYSTEM_ID="your-system-id"
export SYSTEM_SECRET="your-secret"
export SERVER_URL="wss://noprune.org/ws"  # 또는 ws://localhost:8086/ws

# 봇 실행
python examples/random_bot.py
```

## Dependencies

- `websockets>=12.0`
- `python-chess>=1.10.0`
