Files
nanocode/net-games/test_doudizhu_direct.py
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

201 lines
6.6 KiB
Python

"""
斗地主直接API测试 - 三方对战
人类 + 规则AI + DeepSeek AI
"""
import asyncio
import sys
import os
import time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from engine import RoomManager, HumanPlayer, AIPlayer
from doudizhu import DoudizhuGame
from doudizhu.ai_adapters import DoudizhuRuleAI, DoudizhuDeepSeekAI
from config import DEEPSEEK_API_KEY
print("=" * 70)
print(" 🎮 斗地主直接API测试")
print("=" * 70)
print("\n👥 三方对战:")
print(" 1️⃣ 人类玩家 (API模拟)")
print(" 2️⃣ 规则AI (本地算法)")
print(" 3️⃣ DeepSeek AI (大模型API)" if DEEPSEEK_API_KEY else " 3️⃣ DeepSeek AI (回退到规则AI - 未配置API)")
# 重置RoomManager
RoomManager._instance = None
RoomManager._initialized = False
manager = RoomManager()
manager.register_game('doudizhu', DoudizhuGame)
# 创建房间
print("\n📋 创建房间...")
room = manager.create_room('doudizhu', 3, {})
print(f" 房间号: {room.code}")
# 添加玩家
human = HumanPlayer("人类玩家")
room.add_player(human)
ai1 = AIPlayer("规则AI", "rule")
ai1.ai_type = "rule"
room.add_player(ai1)
ai2 = AIPlayer("DeepSeekAI", "deepseek")
ai2.ai_type = "deepseek"
room.add_player(ai2)
print(f"\n 玩家列表:")
for pid, p in room.players.items():
ai_tag = "🤖" if p.is_ai else "👤"
ai_type = getattr(p, 'ai_type', 'human')
print(f" {ai_tag} {p.name} ({ai_type})")
# 创建AI实例
ai_instances = {
ai1.id: DoudizhuRuleAI(),
}
if DEEPSEEK_API_KEY:
ai_instances[ai2.id] = DoudizhuDeepSeekAI(api_key=DEEPSEEK_API_KEY)
else:
ai_instances[ai2.id] = DoudizhuRuleAI()
async def run_ai_turn(game, player_id):
"""运行AI回合"""
player = game.players[player_id]
ai = ai_instances.get(player_id)
if not ai:
return None
# 准备上下文
cards = game.player_cards.get(player_id, [])
is_lord = game.lord_id == player_id
# 计算队友手牌数
teammate_cards = 17
if not is_lord and game.lord_id:
for pid in game.players:
if pid != player_id and pid != game.lord_id:
teammate_cards = len(game.player_cards.get(pid, []))
break
player_context = {
'cards': [c.to_dict() for c in cards],
'is_lord': is_lord,
'teammate_cards': teammate_cards
}
game_state = game.to_dict()
available_actions = game.get_valid_actions(player_id)
# AI决策
try:
decision = await ai.make_decision(game_state, available_actions, player_context)
return decision
except Exception as e:
print(f" ❌ AI错误: {e}")
import traceback
traceback.print_exc()
return {'action': 'pass', 'data': {}}
# 开始游戏
print(f"\n🚀 开始游戏")
manager.start_game(room.id)
game = room.game
print(f"\n🎲 游戏进行中...")
print("-" * 70)
turn_count = 0
max_turns = 50
while turn_count < max_turns:
current_player_id = game.state.current_turn_player_id
current_player = game.players[current_player_id]
# 检查是否是AI
if current_player.is_ai:
# 运行AI
decision = asyncio.run(run_ai_turn(game, current_player_id))
if decision:
action = decision['action']
action_data = decision.get('data', {})
result = game.handle_action(current_player_id, action, action_data)
turn_count += 1
ai_name = current_player.name[:10]
if result.get('success'):
if action == 'play':
card_type = result.get('card_type', {})
print(f"{turn_count:2d}. [{ai_name:10}] 出牌: {card_type.get('name', 'Unknown'):12} "
f"剩余: {result.get('remaining_cards', 0):2d}张")
elif action == 'call':
want = action_data.get('want', False)
if result.get('lord_id'):
lord_name = game.players[result['lord_id']].name
print(f"{turn_count:2d}. [{ai_name:10}] 🎩 叫地主! 地主: {lord_name}")
else:
print(f"{turn_count:2d}. [{ai_name:10}] 叫地主: {'是' if want else '否'}")
elif action == 'pass':
print(f"{turn_count:2d}. [{ai_name:10}] 不出")
else:
print(f"{turn_count:2d}. [{ai_name:10}] ❌ 失败: {result.get('message', 'Unknown')}")
print(f" 可用动作: {game.get_valid_actions(current_player_id)}")
print(f" 决策: {decision}")
else:
# 人类玩家回合 - 简单策略
cards = game.player_cards.get(current_player_id, [])
if game.doudizhu_phase.value == 'calling':
# 叫地主
result = game.handle_action(current_player_id, 'call', {'want': True})
turn_count += 1
if result.get('lord_id'):
print(f"{turn_count:2d}. [人类玩家 ] 🎩 叫地主! 成为地主: {game.players[result['lord_id']].name}")
else:
# 出牌阶段 - 简化:出最小单张
if cards:
result = game.handle_action(current_player_id, 'play', {'card_ids': [cards[0].id]})
turn_count += 1
if result.get('success'):
card_type = result.get('card_type', {})
print(f"{turn_count:2d}. [人类玩家 ] 出牌: {card_type.get('name', 'Unknown'):12} "
f"剩余: {result.get('remaining_cards', 0):2d}张")
else:
# 如果无法出牌,尝试pass
result = game.handle_action(current_player_id, 'pass', {})
if result.get('success'):
print(f"{turn_count:2d}. [人类玩家 ] 不出")
# 检查游戏结束
winner = game.check_winner()
if winner:
winner_name = game.players[winner].name
print(f"\n{'=' * 70}")
print(f"🏆 游戏结束! 获胜者: {winner_name}")
print(f"📊 总回合数: {turn_count}")
print(f"{'=' * 70}")
break
# 小延迟
time.sleep(0.1)
else:
print(f"\n{'=' * 70}")
print(f"⏱️ 达到最大回合数 ({max_turns})")
print(f"{'=' * 70}")
# 最终状态
print(f"\n📋 最终状态:")
for pid, p in game.players.items():
cards = game.player_cards.get(pid, [])
is_lord = "🎩" if game.lord_id == pid else " "
print(f" {is_lord} {p.name:12}: {len(cards):2d}张牌剩余")
print(f"\n✅ 三方对战测试完成!")