Files
aetherbound-guild/runtime/tests/p9_0r10_pair_adaptation_test.gd

150 lines
6.5 KiB
GDScript

extends SceneTree
const MainScene = preload("res://main.tscn")
const PROFESSIONS := ["Hearthguard", "Wayrunner", "Farstring", "Kindhand"]
const ITEMS := ["EQ-002", "EQ-061"]
var failures: Array[String] = []
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
var game := MainScene.instantiate()
game.auto_boot = false
root.add_child(game)
await settle(10)
game.locale = "zh_CN"
game.muted = true
var paths := 0
for left_index in range(PROFESSIONS.size()):
for right_index in range(left_index + 1, PROFESSIONS.size()):
var pair: Array[String] = [PROFESSIONS[left_index], PROFESSIONS[right_index]]
for item in ITEMS:
game.clear_experience()
game.selected_recruits.assign(pair)
expect(game.assign_automatic_formation(), "%s assigns automatic order" % pair_key(pair))
game.begin_first_battle()
resolve_battle(game, false)
expect(game.page == game.AppPage.VICTORY, "%s reaches first Victory" % pair_key(pair))
expect(first_diagnosis_is_truthful(game), "%s first diagnosis names both actual behaviors" % pair_key(pair))
expect(game.coin == 20 and game.first_reward_committed, "%s first reward commits once" % pair_key(pair))
game.open_adaptation()
expect(game.page == game.AppPage.ADAPTATION and game.adaptation_choice.is_empty(), "%s adaptation starts unselected" % pair_key(pair))
expect(game.adaptation_effect("EQ-002").contains("先行者") and game.adaptation_effect("EQ-061").contains("先行者"), "%s equipment language follows automatic lead" % pair_key(pair))
game.choose_adaptation("EQ-061" if item == "EQ-002" else "EQ-002")
game.choose_adaptation(item)
game.begin_second_battle()
expect(game.adaptation_committed and game.adaptation_choice == item, "%s/%s locks revised equipment" % [pair_key(pair), item])
game.choose_adaptation("EQ-061" if item == "EQ-002" else "EQ-002")
expect(game.adaptation_choice == item, "%s/%s rejects post-commit revision" % [pair_key(pair), item])
var elapsed := resolve_battle(game, true)
var expected_hp := expected_lead_hp(game.rear_choice, item)
expect(game.page == game.AppPage.SECOND_RESULT and game.enemy_hp == 0, "%s/%s reaches second Victory" % [pair_key(pair), item])
expect(game.front_hp == expected_hp, "%s/%s lead HP is %d" % [pair_key(pair), item, expected_hp])
expect(is_equal_approx(elapsed, 7.05 if item == "EQ-002" else 6.00), "%s/%s has declared battle time" % [pair_key(pair), item])
expect(game.coin == 20 and game.victory_events == 2, "%s/%s preserves one reward across two victories" % [pair_key(pair), item])
expect(second_action_is_truthful(game), "%s/%s preserves actual second-member action" % [pair_key(pair), item])
expect(result_is_truthful(game, item), "%s/%s result names equipment, lead and second action" % [pair_key(pair), item])
var exceptional := pair == ["Hearthguard", "Wayrunner"] or pair == ["Farstring", "Kindhand"]
expect(game.later_preview_supports_pair() != exceptional, "%s has honest later-preview boundary" % pair_key(pair))
game.clear_experience()
paths += 2
game.selected_recruits.assign(["Farstring", "Kindhand"])
game.assign_automatic_formation()
game.begin_first_battle()
resolve_battle(game, false)
game.open_adaptation()
game.choose_adaptation("EQ-002")
game.begin_second_battle()
resolve_battle(game, true)
game.go_home()
expect(game.page == game.AppPage.MAIN_MENU and game.selected_recruits.is_empty() and game.coin == 0, "Home clears an exceptional pair adaptation")
game.queue_free()
await settle(90)
if failures.is_empty():
print("ABG_P9_0R10_PAIR_ADAPTATION_OK pairs=6 items=2 paths=%d safe_hp=90,100 tempo_hp=70,82 times=7.05,6.00 counter=true ranged=true healing=true reward_once=true boundary=2 cleanup=true" % paths)
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func resolve_battle(game: Control, second: bool) -> float:
var elapsed := 0.0
for phase in range(6):
var duration: float = game.phase_duration(phase)
if second:
game.second_battle_elapsed += duration
elapsed += duration
game.advance_battle_phase()
return elapsed
func first_diagnosis_is_truthful(game: Control) -> bool:
var diagnosis: String = game.victory_explanation()
if not diagnosis.contains(game.candidate_name(game.front_choice)) or not diagnosis.contains(game.candidate_name(game.rear_choice)):
return false
if game.rear_choice == "Wayrunner":
return diagnosis.contains("侧翼反击")
if game.rear_choice == "Farstring":
return diagnosis.contains("远程伤害")
return diagnosis.contains("恢复先行者")
func second_action_is_truthful(game: Control) -> bool:
var feedback: Dictionary = feedback_for_phase(game.battle_feedback_history, 3)
if feedback.is_empty():
return false
var event_text: String = with_phase_text(game, 3)
if game.rear_choice == "Wayrunner":
return feedback["qualifier_zh"] == "侧翼反击" and feedback["target"] == "enemy" and event_text.contains("侧翼反击")
if game.rear_choice == "Farstring":
return feedback["qualifier_zh"] == "后排命中" and feedback["target"] == "enemy" and event_text.contains("远程伤害")
return feedback["qualifier_zh"] == "治疗" and feedback["target"] == "front" and event_text.contains("恢复")
func feedback_for_phase(history: Array[Dictionary], phase: int) -> Dictionary:
for feedback in history:
if feedback["phase"] == phase:
return feedback
return {}
func result_is_truthful(game: Control, item: String) -> bool:
var explanation: String = game.second_result_explanation()
var action_term := "侧翼反击" if game.rear_choice == "Wayrunner" else ("远程伤害" if game.rear_choice == "Farstring" else "恢复")
return explanation.contains(game.adaptation_name(item)) and explanation.contains(game.candidate_name(game.front_choice)) and explanation.contains(game.candidate_name(game.rear_choice)) and explanation.contains(action_term)
func with_phase_text(game: Control, phase: int) -> String:
var previous_phase: int = game.battle_phase
game.battle_phase = phase
var value: String = game.second_battle_event_text()
game.battle_phase = previous_phase
return value
func expected_lead_hp(second_member: String, item: String) -> int:
var base := 90 if item == "EQ-002" else 70
return mini(100, base + 12) if second_member == "Kindhand" else base
func pair_key(pair: Array[String]) -> String:
return "%s+%s" % [pair[0], pair[1]]
func settle(frames: int) -> void:
for frame in range(frames):
await process_frame
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("P9.0R10 pair adaptation: %s" % message)