225 lines
7.9 KiB
Python
225 lines
7.9 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
测试回合制行动限制
|
|||
|
|
- 刚部署单位不能行动(除非有Blitz)
|
|||
|
|
- 单位一回合只能移动或攻击二选一(除非有Tank)
|
|||
|
|
- 单位一回合最多攻击一次(除非有Fury)
|
|||
|
|
"""
|
|||
|
|
import sys
|
|||
|
|
import os
|
|||
|
|
|
|||
|
|
# 添加项目路径
|
|||
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|||
|
|
|
|||
|
|
from kards_battle.core.battle_engine import BattleEngine
|
|||
|
|
from kards_battle.units.unit_loader import load_unit
|
|||
|
|
from interactive.command_parser import CommandParser
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_newly_deployed_unit_cannot_act():
|
|||
|
|
"""测试刚部署的单位不能行动"""
|
|||
|
|
print("=== 测试刚部署单位不能行动 ===")
|
|||
|
|
|
|||
|
|
engine = BattleEngine("Germany", "USA", debug_mode=True)
|
|||
|
|
parser = CommandParser(engine)
|
|||
|
|
|
|||
|
|
# 部署一个普通单位(没有BLITZ)
|
|||
|
|
grenadier = load_unit('ger_infantry_grenadier')
|
|||
|
|
engine.deploy_unit_to_support(grenadier, 0)
|
|||
|
|
engine.debug_set_kredits(0, kredits=5)
|
|||
|
|
|
|||
|
|
print(f"单位关键词: {grenadier.keywords}")
|
|||
|
|
print(f"单位状态: deployed_this_turn={grenadier.deployed_this_turn}")
|
|||
|
|
print(f" can_operate_immediately={grenadier.can_operate_immediately}")
|
|||
|
|
|
|||
|
|
# 尝试移动刚部署的单位
|
|||
|
|
print("\n尝试移动刚部署的单位:")
|
|||
|
|
success, message = parser.parse("move 1 0")
|
|||
|
|
print(f"移动结果: {success} - {message}")
|
|||
|
|
assert not success, "刚部署的单位应该不能移动"
|
|||
|
|
assert "deployed this turn" in message, f"错误信息应该提到部署限制: {message}"
|
|||
|
|
|
|||
|
|
# 尝试攻击
|
|||
|
|
print("\n尝试攻击:")
|
|||
|
|
# 需要有目标,先部署敌军
|
|||
|
|
marine = load_unit('usa_infantry_marine')
|
|||
|
|
engine.deploy_unit_to_support(marine, 1)
|
|||
|
|
|
|||
|
|
success, message = parser.parse("attack S1 S0")
|
|||
|
|
print(f"攻击结果: {success} - {message}")
|
|||
|
|
assert not success, "刚部署的单位应该不能攻击"
|
|||
|
|
assert "deployed this turn" in message, f"错误信息应该提到部署限制: {message}"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_blitz_unit_can_act_immediately():
|
|||
|
|
"""测试有Blitz关键词的单位可以立即行动"""
|
|||
|
|
print("\n=== 测试Blitz单位立即行动 ===")
|
|||
|
|
|
|||
|
|
engine = BattleEngine("Germany", "USA", debug_mode=True)
|
|||
|
|
parser = CommandParser(engine)
|
|||
|
|
|
|||
|
|
# 部署一个有Blitz的单位
|
|||
|
|
stormtrooper = load_unit('ger_infantry_stormtrooper') # 应该有BLITZ关键词
|
|||
|
|
engine.deploy_unit_to_support(stormtrooper, 0)
|
|||
|
|
engine.debug_set_kredits(0, kredits=5)
|
|||
|
|
|
|||
|
|
print(f"单位关键词: {stormtrooper.keywords}")
|
|||
|
|
print(f"can_operate_immediately: {stormtrooper.can_operate_immediately}")
|
|||
|
|
|
|||
|
|
if stormtrooper.has_keyword("BLITZ"):
|
|||
|
|
# 尝试移动Blitz单位
|
|||
|
|
print("\n尝试移动Blitz单位:")
|
|||
|
|
success, message = parser.parse("move 1 0")
|
|||
|
|
print(f"移动结果: {success} - {message}")
|
|||
|
|
assert success, f"Blitz单位应该能立即移动: {message}"
|
|||
|
|
else:
|
|||
|
|
print("注意: Stormtrooper没有BLITZ关键词,跳过此测试")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_move_or_attack_restriction():
|
|||
|
|
"""测试移动或攻击二选一限制"""
|
|||
|
|
print("\n=== 测试移动攻击二选一 ===")
|
|||
|
|
|
|||
|
|
engine = BattleEngine("Germany", "USA", debug_mode=True)
|
|||
|
|
parser = CommandParser(engine)
|
|||
|
|
|
|||
|
|
# 部署单位并让其可以行动
|
|||
|
|
panzer = load_unit('ger_tank_panzer_iv') # Tank有BLITZ和移动攻击能力
|
|||
|
|
engine.deploy_unit_to_support(panzer, 0)
|
|||
|
|
engine.debug_set_kredits(0, kredits=10)
|
|||
|
|
|
|||
|
|
# 结束回合让单位状态重置
|
|||
|
|
engine.end_turn() # 切换到美军
|
|||
|
|
engine.end_turn() # 切换回德军,新回合开始
|
|||
|
|
engine.debug_set_kredits(0, kredits=10)
|
|||
|
|
|
|||
|
|
print(f"单位状态: deployed_this_turn={panzer.deployed_this_turn}")
|
|||
|
|
print(f" can_move_and_attack={panzer.can_move_and_attack}")
|
|||
|
|
|
|||
|
|
# 先移动
|
|||
|
|
print("\n1. 移动单位:")
|
|||
|
|
success, message = parser.parse("move 1 0")
|
|||
|
|
print(f"移动结果: {success} - {message}")
|
|||
|
|
|
|||
|
|
if success:
|
|||
|
|
print(f"移动后状态: has_moved_this_turn={panzer.has_moved_this_turn}")
|
|||
|
|
|
|||
|
|
# 再尝试攻击
|
|||
|
|
print("\n2. 移动后尝试攻击:")
|
|||
|
|
# 部署目标
|
|||
|
|
marine = load_unit('usa_infantry_marine')
|
|||
|
|
engine.deploy_unit_to_support(marine, 1)
|
|||
|
|
|
|||
|
|
success, message = parser.parse("attack F0 S0")
|
|||
|
|
print(f"攻击结果: {success} - {message}")
|
|||
|
|
|
|||
|
|
if panzer.can_move_and_attack:
|
|||
|
|
print("Tank单位应该可以移动后攻击")
|
|||
|
|
else:
|
|||
|
|
assert not success, "普通单位移动后应该不能攻击"
|
|||
|
|
assert "has moved" in message, f"错误信息应该提到移动限制: {message}"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_multiple_attack_restriction():
|
|||
|
|
"""测试多次攻击限制"""
|
|||
|
|
print("\n=== 测试攻击次数限制 ===")
|
|||
|
|
|
|||
|
|
engine = BattleEngine("Germany", "USA", debug_mode=True)
|
|||
|
|
parser = CommandParser(engine)
|
|||
|
|
|
|||
|
|
# 部署攻击单位
|
|||
|
|
grenadier = load_unit('ger_infantry_grenadier')
|
|||
|
|
engine.deploy_unit_to_support(grenadier, 0)
|
|||
|
|
engine.debug_set_kredits(0, kredits=20)
|
|||
|
|
|
|||
|
|
# 部署多个目标
|
|||
|
|
for i in range(3):
|
|||
|
|
marine = load_unit('usa_infantry_marine')
|
|||
|
|
engine.deploy_unit_to_support(marine, 1)
|
|||
|
|
|
|||
|
|
# 结束回合让单位可以行动
|
|||
|
|
engine.end_turn() # 切换到美军
|
|||
|
|
engine.end_turn() # 切换回德军,新回合开始
|
|||
|
|
engine.debug_set_kredits(0, kredits=20)
|
|||
|
|
|
|||
|
|
print(f"最大攻击次数: {grenadier.max_attacks_per_turn}")
|
|||
|
|
|
|||
|
|
# 第一次攻击
|
|||
|
|
print("\n1. 第一次攻击:")
|
|||
|
|
success, message = parser.parse("attack S1 S0")
|
|||
|
|
print(f"攻击结果: {success} - {message}")
|
|||
|
|
|
|||
|
|
if success:
|
|||
|
|
print(f"攻击次数: {grenadier.attacks_this_turn}")
|
|||
|
|
|
|||
|
|
# 第二次攻击
|
|||
|
|
print("\n2. 第二次攻击:")
|
|||
|
|
success, message = parser.parse("attack S1 S1")
|
|||
|
|
print(f"攻击结果: {success} - {message}")
|
|||
|
|
|
|||
|
|
if grenadier.can_attack_multiple_times:
|
|||
|
|
print("有Fury等能力的单位可以多次攻击")
|
|||
|
|
else:
|
|||
|
|
assert not success, "普通单位应该不能攻击两次"
|
|||
|
|
assert "maximum attacks" in message, f"错误信息应该提到攻击次数限制: {message}"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_tank_abilities():
|
|||
|
|
"""测试Tank类单位的特殊能力"""
|
|||
|
|
print("\n=== 测试Tank单位特殊能力 ===")
|
|||
|
|
|
|||
|
|
engine = BattleEngine("Germany", "USA", debug_mode=True)
|
|||
|
|
parser = CommandParser(engine)
|
|||
|
|
|
|||
|
|
# 部署Tank单位
|
|||
|
|
panzer = load_unit('ger_tank_panzer_iv')
|
|||
|
|
engine.deploy_unit_to_support(panzer, 0)
|
|||
|
|
engine.debug_set_kredits(0, kredits=20)
|
|||
|
|
|
|||
|
|
# 部署目标
|
|||
|
|
marine = load_unit('usa_infantry_marine')
|
|||
|
|
engine.deploy_unit_to_support(marine, 1)
|
|||
|
|
|
|||
|
|
# 结束回合让单位可以行动
|
|||
|
|
engine.end_turn() # 切换到美军
|
|||
|
|
engine.end_turn() # 切换回德军,新回合开始
|
|||
|
|
engine.debug_set_kredits(0, kredits=20)
|
|||
|
|
|
|||
|
|
print(f"Tank能力: can_move_and_attack={panzer.can_move_and_attack}")
|
|||
|
|
print(f"单位类型: {panzer.unit_type}")
|
|||
|
|
|
|||
|
|
if panzer.can_move_and_attack:
|
|||
|
|
# Tank应该可以移动后攻击
|
|||
|
|
print("\n1. Tank移动:")
|
|||
|
|
success, message = parser.parse("move 1 0")
|
|||
|
|
print(f"移动结果: {success} - {message}")
|
|||
|
|
|
|||
|
|
if success:
|
|||
|
|
print("\n2. Tank移动后攻击:")
|
|||
|
|
success, message = parser.parse("attack F0 S0")
|
|||
|
|
print(f"攻击结果: {success} - {message}")
|
|||
|
|
assert success, f"Tank应该能移动后攻击: {message}"
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
print("开始回合制限制测试\n")
|
|||
|
|
|
|||
|
|
tests = [
|
|||
|
|
test_newly_deployed_unit_cannot_act,
|
|||
|
|
test_blitz_unit_can_act_immediately,
|
|||
|
|
test_move_or_attack_restriction,
|
|||
|
|
test_multiple_attack_restriction,
|
|||
|
|
test_tank_abilities,
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
for test in tests:
|
|||
|
|
try:
|
|||
|
|
test()
|
|||
|
|
print("✅ 测试通过")
|
|||
|
|
except AssertionError as e:
|
|||
|
|
print(f"❌ 测试失败: {e}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"❌ 测试异常: {e}")
|
|||
|
|
print("-" * 50)
|
|||
|
|
|
|||
|
|
print("\n回合制限制测试完成")
|