""" 斗地主三方对战完整测试 人类 + 规则AI + DeepSeek AI """ import sys import os import time import threading import asyncio 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(" 🎮 斗地主三方对战测试") print("=" * 70) print("\n👥 玩家配置:") print(" 1️⃣ 人类玩家 (通过API模拟)") print(" 2️⃣ 规则AI (本地算法)") print(" 3️⃣ DeepSeek AI (大模型API)") print(f"\n🔑 DeepSeek API: {'已配置' if DEEPSEEK_API_KEY else '未配置'}") # 重置并创建管理器 RoomManager._instance = None RoomManager._initialized = False manager = RoomManager() manager.register_game('doudizhu', DoudizhuGame) # 创建房间 print("\n" + "-" * 70) print("📋 创建房间") 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})") # 开始游戏 print(f"\n🚀 开始游戏") success, message = manager.start_game(room.id) print(f" 结果: {message}") game = room.game turn_count = 0 max_turns = 30 # 最多30步 # 创建AI实例 ai_instances = { ai1.id: DoudizhuRuleAI(), } if DEEPSEEK_API_KEY: ai_instances[ai2.id] = DoudizhuDeepSeekAI(api_key=DEEPSEEK_API_KEY) else: print(f"\n⚠️ DeepSeek API未配置,DeepSeekAI将回退到规则AI") ai_instances[ai2.id] = DoudizhuRuleAI() async def run_ai_turn(player_id, game): """运行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}") return {'action': 'pass', 'data': {}} print(f"\n🎲 游戏进行中...") print("-" * 70) # 游戏主循环 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(current_player_id, game)) 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')}") 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}. [人类玩家 ] 🎩 叫地主! 成为地主") 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}张") # 检查游戏结束 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✅ 三方对战测试完成!")