UNO card game web app (Node.js/React) with Miku bot integration. Previously an independent git repo (fork of mizanxali/uno-online). Removed .git/ and absorbed into main repo for unified tracking. Includes bot integration code: botActionExecutor, cardParser, gameStateBuilder, and server-side bot action support. 37 files, node_modules excluded via local .gitignore.
7.2 KiB
7.2 KiB
🤖 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
curl http://localhost:5000/api/game/ABC123/state
3. Send a bot action (when it's Player 2's turn)
# 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:
# 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
{
"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 totrueto call UNO with this play
Draw a Card
{
"action": "draw"
}
Call UNO
{
"action": "uno"
}
Card Codes Reference
Number Cards
0R,1R, ...,9R- Red numbers0G,1G, ...,9G- Green numbers0B,1B, ...,9B- Blue numbers0Y,1Y, ...,9Y- Yellow numbers
Action Cards
skipR,skipG,skipB,skipY- Skip cards_R,_G,_B,_Y- Reverse cardsD2R,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 pileplayer1: 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 playbotContext: Helper info (canPlay, mustDraw, hasUno, actions)
Validation Rules
The game validates bot actions:
- Turn validation: Must be Player 2's turn
- Card validation: Card must be in Player 2's hand
- Playability: Card must be playable on current card
- Wild cards: Must specify color for "W" and "D4W"
- UNO: Can only call with exactly 2 cards in hand
Integration with Miku Bot
From Python (Miku bot)
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
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<EFBFBD><EFBFBD> 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 specificationBOT_INTEGRATION_COMPLETE.md- This fileclient/src/utils/botActionExecutor.js- Bot action executortest-bot-action.js- Test script
Modified Files
server.js- HTTP API endpoints for bot actionsclient/src/components/Game.js- Bot action listener and integration
Next Steps
- Test the integration: Use
test-bot-action.jsto verify actions work - Integrate with Miku: Add UNO game support to Miku bot
- Add LLM strategy: Use Miku's LLM to make strategic decisions
- Add personality: Make Miku trash talk and celebrate!
Example Full Game Flow
# 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!