# Bot Action Specification for UNO Game

## Overview
The bot (Miku) can interact with the UNO game by sending JSON action commands. The game state is provided in a structured JSON format, and the bot responds with action commands.

## Action Types

### 1. Play a Card
```json
{
  "action": "play",
  "card": "4R",
  "color": null
}
```
- `action`: Must be `"play"`
- `card`: The card code to play (e.g., "4R", "D2G", "skipB", "W", "D4W")
- `color`: Optional. Only required for wild cards ("W" or "D4W"). Values: "R", "G", "B", or "Y"

**Examples:**
```json
// Play a number card
{"action": "play", "card": "4R", "color": null}

// Play a Draw 2 card
{"action": "play", "card": "D2G", "color": null}

// Play a Skip card
{"action": "play", "card": "skipB", "color": null}

// Play a Wild card (must specify color)
{"action": "play", "card": "W", "color": "R"}

// Play a Wild Draw 4 (must specify color)
{"action": "play", "card": "D4W", "color": "B"}
```

### 2. Draw a Card
```json
{
  "action": "draw"
}
```
- `action`: Must be `"draw"`
- No other parameters needed

### 3. Call UNO
```json
{
  "action": "uno"
}
```
- `action`: Must be `"uno"`
- Call this when you have exactly 2 cards in hand and are about to play one
- **Important:** Call UNO *before* playing your second-to-last card, or call it as a separate action

### 4. Combined Actions (Play + UNO)
```json
{
  "action": "play",
  "card": "4R",
  "color": null,
  "callUno": true
}
```
- Add `"callUno": true` when playing a card that will leave you with 1 card

## Card Code Reference

### Number Cards
- Format: `{number}{color}`
- Numbers: 0-9
- Colors: R (Red), G (Green), B (Blue), Y (Yellow)
- Examples: `0R`, `5G`, `9B`, `3Y`

### Action Cards
- **Skip**: `skipR`, `skipG`, `skipB`, `skipY`
- **Reverse**: `_R`, `_G`, `_B`, `_Y`
- **Draw 2**: `D2R`, `D2G`, `D2B`, `D2Y`
- **Wild**: `W`
- **Wild Draw 4**: `D4W`

## Color Codes
- `R` - Red
- `G` - Green
- `B` - Blue
- `Y` - Yellow

## Strategy Tips for Bot

### When to Play Cards
1. Check `botContext.canPlay` - if false, you must draw
2. Look at `player2.playableCards` for available moves
3. Match by color or number with `currentCard`

### Priority Strategy
1. **Action cards first** (Skip, Draw 2, Wild Draw 4) to disrupt opponent
2. **Match color** if opponent has few cards (to block them)
3. **Match number** to change color advantageously
4. **Save wild cards** for critical moments

### When to Call UNO
- When you have exactly 2 cards and are about to play one
- **Must call UNO** or you'll get 2 penalty cards!

### When to Use Wild Cards
- When you have no other playable cards
- To change to a color you have many of
- Wild Draw 4: When opponent has 1-2 cards (aggressive)

## HTTP API Endpoint

### Get Game State
```
GET http://localhost:5000/api/game/\{roomCode\}/state
```

**Response:**
```json
{
  "success": true,
  "gameState": { /* full game state */ },
  "timestamp": "2026-01-27T..."
}
```

### Submit Bot Action
```
POST http://localhost:5000/api/game/\{roomCode\}/action
Content-Type: application/json

{
  "action": "play",
  "card": "4R",
  "color": null
}
```

**Response:**
```json
{
  "success": true,
  "message": "Action received and forwarded to game"
}
```

## Error Handling

### Invalid Actions
The game will ignore invalid actions:
- Playing a card not in your hand
- Playing an unplayable card
- Not specifying color for wild cards
- Playing out of turn

### Validation
Before sending an action:
1. Verify it's Player 2's turn (`game.currentTurn === "Player 2"`)
2. Check card is in `player2.cards` array
3. Verify card is in `player2.playableCards` array
4. For wild cards, always specify a valid color

## Example Bot Decision Flow

```python
def make_move(game_state):
    # Check if it's our turn
    if game_state['game']['currentTurn'] != 'Player 2':
        return None
    
    # Check if we can play
    if not game_state['botContext']['canPlay']:
        return {"action": "draw"}
    
    # Get playable cards
    playable = game_state['player2']['playableCards']
    
    if not playable:
        return {"action": "draw"}
    
    # Check if we need to call UNO
    our_cards = game_state['player2']['cardCount']
    call_uno = (our_cards == 2)
    
    # Priority: Draw 2 or Draw 4
    for card in playable:
        if card['type'] in ['draw2', 'draw4']:
            action = {"action": "play", "card": card['code']}
            if card['type'] == 'draw4':
                action['color'] = choose_best_color(game_state)
            if call_uno:
                action['callUno'] = True
            return action
    
    # Priority: Skip or Reverse
    for card in playable:
        if card['type'] in ['skip', 'reverse']:
            if call_uno:
                return {"action": "play", "card": card['code'], "callUno": True}
            return {"action": "play", "card": card['code']}
    
    # Play any available card
    card = playable[0]
    action = {"action": "play", "card": card['code']}
    if card['type'] == 'wild':
        action['color'] = choose_best_color(game_state)
    if call_uno:
        action['callUno'] = True
    return action
```

## WebSocket Events (Alternative to HTTP)

If the bot maintains a WebSocket connection:

### Emit bot action:
```javascript
socket.emit('botAction', {
  action: 'play',
  card: '4R',
  color: null
})
```

### Receive game state updates:
```javascript
socket.on('updateGameState', (state) => {
  // Process new game state
})
```
