# 🤖 Bot Integration Complete Guide ## Overview The UNO game now supports bot players (Miku) making moves via JSON API. The bot can play cards, draw cards, and call UNO by sending structured JSON commands. ## Quick Start ### 1. Start a game with 2 players - Player 1: Create a room (e.g., room code "ABC123") - Player 2: Join the same room - Game will auto-start when both players are present ### 2. Get the current game state ```bash curl http://localhost:5000/api/game/ABC123/state ``` ### 3. Send a bot action (when it's Player 2's turn) ```bash # Draw a card curl -X POST http://localhost:5000/api/game/ABC123/action \ -H "Content-Type: application/json" \ -d '{"action":"draw"}' # Play a card curl -X POST http://localhost:5000/api/game/ABC123/action \ -H "Content-Type: application/json" \ -d '{"action":"play","card":"4R"}' # Play a wild card with color choice curl -X POST http://localhost:5000/api/game/ABC123/action \ -H "Content-Type: application/json" \ -d '{"action":"play","card":"W","color":"R"}' # Call UNO curl -X POST http://localhost:5000/api/game/ABC123/action \ -H "Content-Type: application/json" \ -d '{"action":"uno"}' ``` ## Testing Bot Actions Use the included test script: ```bash # Test drawing a card node test-bot-action.js ABC123 '{"action":"draw"}' # Test playing a card node test-bot-action.js ABC123 '{"action":"play","card":"4R"}' # Test playing a wild card node test-bot-action.js ABC123 '{"action":"play","card":"W","color":"B"}' ``` ## Action Format Specification ### Play a Card ```json { "action": "play", "card": "4R", "color": null, "callUno": false } ``` **Parameters:** - `action` (string, required): Must be `"play"` - `card` (string, required): Card code (e.g., "4R", "D2G", "skipB", "W", "D4W") - `color` (string, optional): Required for wild cards ("W", "D4W"). Values: "R", "G", "B", "Y" - `callUno` (boolean, optional): Set to `true` to call UNO with this play ### Draw a Card ```json { "action": "draw" } ``` ### Call UNO ```json { "action": "uno" } ``` ## Card Codes Reference ### Number Cards - `0R`, `1R`, ..., `9R` - Red numbers - `0G`, `1G`, ..., `9G` - Green numbers - `0B`, `1B`, ..., `9B` - Blue numbers - `0Y`, `1Y`, ..., `9Y` - Yellow numbers ### Action Cards - `skipR`, `skipG`, `skipB`, `skipY` - Skip cards - `_R`, `_G`, `_B`, `_Y` - Reverse cards - `D2R`, `D2G`, `D2B`, `D2Y` - Draw 2 cards ### Wild Cards - `W` - Wild (change color) - `D4W` - Wild Draw 4 (change color + opponent draws 4) ## Game State Structure The game state JSON includes: - `game`: Overall game status (isOver, winner, currentTurn, turnNumber) - `currentCard`: The card on top of the discard pile - `player1`: Player 1's info and cards (hidden from bot) - `player2`: Player 2's (bot's) info and cards (visible) - `player2.playableCards`: Array of cards the bot can currently play - `botContext`: Helper info (canPlay, mustDraw, hasUno, actions) ## Validation Rules The game validates bot actions: 1. **Turn validation**: Must be Player 2's turn 2. **Card validation**: Card must be in Player 2's hand 3. **Playability**: Card must be playable on current card 4. **Wild cards**: Must specify color for "W" and "D4W" 5. **UNO**: Can only call with exactly 2 cards in hand ## Integration with Miku Bot ### From Python (Miku bot) ```python import requests import json def get_game_state(room_code): response = requests.get(f'http://localhost:5000/api/game/{room_code}/state') return response.json()['gameState'] def send_bot_action(room_code, action): response = requests.post( f'http://localhost:5000/api/game/{room_code}/action', headers={'Content-Type': 'application/json'}, data=json.dumps(action) ) return response.json() # Example: Make a strategic move state = get_game_state('ABC123') if state['game']['currentTurn'] == 'Player 2': playable = state['player2']['playableCards'] if playable: # Play first playable card card = playable[0] action = {'action': 'play', 'card': card['code']} # Handle wild cards if card['type'] in ['wild', 'draw4']: action['color'] = 'R' # Choose a color # Call UNO if needed if state['player2']['cardCount'] == 2: action['callUno'] = True result = send_bot_action('ABC123', action) print(f"Played {card['displayName']}: {result}") else: # Must draw result = send_bot_action('ABC123', {'action': 'draw'}) print(f"Drew a card: {result}") ``` ### LLM Integration Example ```python def miku_make_move(game_state): """Use LLM to decide Miku's move""" # Build prompt for LLM prompt = f""" You are playing UNO. It's your turn. Current card on table: {game_state['currentCard']['displayName']} Your cards: {[c['displayName'] for c in game_state['player2']['cards']]} Playable cards: {[c['displayName'] for c in game_state['player2']['playableCards']]} Opponent has {game_state['player1']['cardCount']} cards. You have {game_state['player2']['cardCount']} cards. Choose your move as JSON: {{"action": "play", "card": "CODE"}} or {{"action": "draw"}} """ # Get LLM response llm_response = query_llama(prompt) # Parse JSON from response action = json.loads(llm_response) # Send action return send_bot_action(game_state['room'], action) ``` ## Debugging ### Console Logs The game client logs bot actions: - `🤖 Received bot action:` - Action received from HTTP API - `🤖 Bot action result:` - Result of executing the action - `�� Bot playing card:` - Card being played - `🌈 Bot chose color:` - Color chosen for wild card - `🔥 Bot called UNO!` - UNO was called - `📥 Bot drawing a card` - Card was drawn ### Error Messages - `❌ Bot action rejected: Not Player 2's turn` - Wrong turn - `❌ Bot play action rejected: Card not in hand` - Invalid card - `❌ Bot play action rejected: Wild card without color` - Missing color - `❌ Bot UNO rejected` - Invalid UNO call ## Files Added/Modified ### New Files - `BOT_ACTION_SPEC.md` - Detailed API specification - `BOT_INTEGRATION_COMPLETE.md` - This file - `client/src/utils/botActionExecutor.js` - Bot action executor - `test-bot-action.js` - Test script ### Modified Files - `server.js` - HTTP API endpoints for bot actions - `client/src/components/Game.js` - Bot action listener and integration ## Next Steps 1. **Test the integration**: Use `test-bot-action.js` to verify actions work 2. **Integrate with Miku**: Add UNO game support to Miku bot 3. **Add LLM strategy**: Use Miku's LLM to make strategic decisions 4. **Add personality**: Make Miku trash talk and celebrate! ## Example Full Game Flow ```bash # Terminal 1: Start server cd /home/koko210Serve/docker/uno-online npm start # Terminal 2: Start client dev server cd /home/koko210Serve/docker/uno-online/client npm start # Browser 1: Create game as Player 1 # Open http://localhost:3000 # Create room "MIKU01" # Browser 2: Join as Player 2 # Open http://localhost:3000 # Join room "MIKU01" # Terminal 3: Control Player 2 (bot) via API # Get state curl http://localhost:5000/api/game/MIKU01/state | jq # Make a move (when it's Player 2's turn) node test-bot-action.js MIKU01 '{"action":"play","card":"4R"}' ``` 🎉 The bot integration is complete and ready to use!