kards-env/tests/test_turn_and_resources.py

253 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
回合流逝和资源系统测试 - 使用pytest
测试Kredits Slot增长、Kredits补满、上限限制等
"""
import pytest
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from kards_battle.core.battle_engine import BattleEngine
class TestTurnProgression:
"""测试回合流逝系统"""
def setup_method(self):
"""每个测试前的设置"""
self.engine = BattleEngine("Germany", "USA", debug_mode=True)
def test_kredits_slot_increases_with_turns(self):
"""测试随回合Slots增加Kredits补满"""
# 验证初始状态
assert self.engine.get_kredits_slot(0) == 1 # 德军初始slot
assert self.engine.get_kredits_slot(1) == 0 # 美军初始slot
assert self.engine.get_kredits(0) == 1 # 德军初始kredits
assert self.engine.get_kredits(1) == 0 # 美军初始kredits
# 进行几轮完整回合
for turn in range(2, 6): # 测试回合2-5
# 德军回合结束,切换到美军
result1 = self.engine.end_turn()
assert result1['new_active_player'] == 1
assert result1['turn_phase'] == 1
assert not result1['is_new_round']
# 美军获得资源
assert self.engine.get_kredits_slot(1) == turn - 1
assert self.engine.get_kredits(1) == turn - 1
# 美军回合结束,切换到德军(新回合开始)
result2 = self.engine.end_turn()
assert result2['new_active_player'] == 0
assert result2['turn_phase'] == 0
assert result2['is_new_round']
assert result2['turn_number'] == turn
# 德军获得新回合资源
assert self.engine.get_kredits_slot(0) == turn
assert self.engine.get_kredits(0) == turn
def test_kredits_slot_caps_at_12(self):
"""测试Kredits Slot达到12时不应再自动增加"""
# 快速推进到slot接近12的回合
self.engine.debug_set_kredits(0, kredits_slot=11)
self.engine.debug_set_kredits(1, kredits_slot=11)
# 进行几轮回合验证不超过12
for _ in range(5):
self.engine.end_turn() # 德→美
# 美军slot不应超过12
assert self.engine.get_kredits_slot(1) <= 12
self.engine.end_turn() # 美→德(新回合)
# 德军slot不应超过12
assert self.engine.get_kredits_slot(0) <= 12
# 最终验证都是12
assert self.engine.get_kredits_slot(0) == 12
assert self.engine.get_kredits_slot(1) == 12
def test_kredits_caps_at_24_absolute_max(self):
"""测试Kredits超过24时自动设为24绝对上限"""
# 尝试设置超过绝对上限的Kredits
result1 = self.engine.debug_set_kredits(0, kredits=30)
assert result1['success']
assert result1['changes']['kredits'] == 24 # 应该被限制为24
assert self.engine.get_kredits(0) == 24
# 尝试设置超过绝对上限的Slot
result2 = self.engine.debug_set_kredits(1, kredits_slot=30)
assert result2['success']
assert result2['changes']['kredits_slot'] == 24 # 应该被限制为24
assert self.engine.get_kredits_slot(1) == 24
def test_kredits_reset_to_slot_each_turn(self):
"""测试每回合Kredits重置为Slot数值"""
# 设置slot和消耗一些kredits
self.engine.debug_set_kredits(0, kredits_slot=5, kredits=2) # slot=5, 当前=2
initial_slot = self.engine.get_kredits_slot(0)
initial_kredits = self.engine.get_kredits(0)
assert initial_slot == 5
assert initial_kredits == 2
# 切换回合应该重置Kredits为Slot值
self.engine.end_turn() # 德→美
self.engine.end_turn() # 美→德新回合重置Kredits
# 德军Kredits应该重置为slot+1因为新回合slot会增长
final_slot = self.engine.get_kredits_slot(0)
final_kredits = self.engine.get_kredits(0)
assert final_slot == initial_slot + 1 # slot增长了1
assert final_kredits == final_slot # kredits重置为新的slot值
def test_turn_phases_alternate_correctly(self):
"""测试:回合阶段正确轮换"""
# 验证初始状态回合1阶段0德军
assert self.engine.current_turn == 1
assert self.engine.turn_phase == 0
assert self.engine.active_player == 0
# 第一次切换回合1阶段1美军
result1 = self.engine.end_turn()
assert result1['turn_number'] == 1
assert result1['turn_phase'] == 1
assert result1['new_active_player'] == 1
assert not result1['is_new_round']
# 第二次切换回合2阶段0德军新回合
result2 = self.engine.end_turn()
assert result2['turn_number'] == 2
assert result2['turn_phase'] == 0
assert result2['new_active_player'] == 0
assert result2['is_new_round']
# 第三次切换回合2阶段1美军
result3 = self.engine.end_turn()
assert result3['turn_number'] == 2
assert result3['turn_phase'] == 1
assert result3['new_active_player'] == 1
assert not result3['is_new_round']
def test_both_players_get_resources_in_their_phase(self):
"""测试:双方在各自阶段都能获得正确资源"""
# 进行完整的几轮游戏
turn_data = []
for i in range(8): # 8次切换 = 4个完整回合
turn_info = {
'step': i + 1,
'turn': self.engine.current_turn,
'phase': self.engine.turn_phase,
'active': self.engine.active_player,
'ger_slot': self.engine.get_kredits_slot(0),
'ger_kredits': self.engine.get_kredits(0),
'usa_slot': self.engine.get_kredits_slot(1),
'usa_kredits': self.engine.get_kredits(1)
}
turn_data.append(turn_info)
self.engine.end_turn()
# 验证资源增长模式
# 德军应该在每个新回合开始时增长slot
# 美军应该在每次轮到自己时增长slot
# 检查德军资源增长在phase=0时
ger_turns = [t for t in turn_data if t['active'] == 0]
for i, turn in enumerate(ger_turns):
expected_slot = i + 1 # 德军slot应该等于轮数
assert turn['ger_slot'] == expected_slot, f"德军第{i+1}轮slot应为{expected_slot},实际为{turn['ger_slot']}"
assert turn['ger_kredits'] == expected_slot, f"德军第{i+1}轮kredits应为{expected_slot},实际为{turn['ger_kredits']}"
# 检查美军资源增长在phase=1时
usa_turns = [t for t in turn_data if t['active'] == 1]
for i, turn in enumerate(usa_turns):
expected_slot = i + 1 # 美军slot应该等于轮数
assert turn['usa_slot'] == expected_slot, f"美军第{i+1}轮slot应为{expected_slot},实际为{turn['usa_slot']}"
assert turn['usa_kredits'] == expected_slot, f"美军第{i+1}轮kredits应为{expected_slot},实际为{turn['usa_kredits']}"
def test_spend_kredits_correctly(self):
"""测试正确扣除Kredits"""
self.engine.debug_set_kredits(0, kredits=10)
# 扣除3点
result = self.engine.spend_kredits(0, 3)
assert result is True
assert self.engine.get_kredits(0) == 7
# 扣除超过现有的点数
result = self.engine.spend_kredits(0, 10)
assert result is False
assert self.engine.get_kredits(0) == 7 # 不应该变化
# 扣除0点
result = self.engine.spend_kredits(0, 0)
assert result is True
assert self.engine.get_kredits(0) == 7 # 不应该变化
# 扣除负数
result = self.engine.spend_kredits(0, -1)
assert result is True
assert self.engine.get_kredits(0) == 7 # 不应该变化
class TestResourceLimits:
"""测试资源限制"""
def setup_method(self):
"""每个测试前的设置"""
self.engine = BattleEngine("Germany", "USA", debug_mode=True)
def test_natural_slot_growth_stops_at_12(self):
"""测试自然增长的slot在12处停止"""
# 设置slot接近上限
self.engine.debug_set_kredits(0, kredits_slot=10)
self.engine.debug_set_kredits(1, kredits_slot=10)
# 进行多轮游戏
for _ in range(10): # 进行10轮完整回合
self.engine.end_turn() # 德→美
self.engine.end_turn() # 美→德
# 验证slot都停在12
assert self.engine.get_kredits_slot(0) == 12
assert self.engine.get_kredits_slot(1) == 12
# 再进行几轮确认不会超过12
for _ in range(5):
self.engine.end_turn()
self.engine.end_turn()
assert self.engine.get_kredits_slot(0) == 12
assert self.engine.get_kredits_slot(1) == 12
def test_debug_set_respects_absolute_limits(self):
"""测试DEBUG设置尊重绝对限制"""
# 测试正常范围内的设置
result = self.engine.debug_set_kredits(0, kredits=15, kredits_slot=15)
assert result['success']
assert result['changes']['kredits'] == 15
assert result['changes']['kredits_slot'] == 15
# 测试超出绝对上限的设置
result = self.engine.debug_set_kredits(0, kredits=50, kredits_slot=50)
assert result['success']
assert result['changes']['kredits'] == 24 # 被限制为24
assert result['changes']['kredits_slot'] == 24 # 被限制为24
# 测试负数设置
result = self.engine.debug_set_kredits(0, kredits=-5, kredits_slot=-5)
assert result['success']
assert result['changes']['kredits'] == 0 # 被限制为0
assert result['changes']['kredits_slot'] == 0 # 被限制为0
if __name__ == "__main__":
pytest.main([__file__, "-v"])