a
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
"""
|
||||
斗地主三方对战完整测试
|
||||
人类 + 规则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✅ 三方对战测试完成!")
|
||||
Reference in New Issue
Block a user