Files
DirtyLeague_Bot/test_full_loop.py

106 lines
3.3 KiB
Python

"""
Controlled single-cycle integration test:
Runs 1 full cycle starting from TOWER_LOBBY:
1. Detect TOWER_LOBBY
2. Read trophies and chests
3. Enter Fight
4. Handle IN_GAME until outcome (Victory / Defeat / Surrender)
5. Handle Result screen (Collect / OK / Remove chest if no slots)
6. Verify clean return to TOWER_LOBBY
"""
import json
import logging
import sys
import time
from bot_core import DirtyLeagueBot, GameState
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[logging.StreamHandler(sys.stdout)]
)
def run_single_cycle_test(timeout_sec: int = 180):
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
bot = DirtyLeagueBot(config)
logging.info("=== Starting Controlled Full Cycle Test ===")
logging.info(f"Timeout: {timeout_sec}s. Press Ctrl+C to abort.")
start_time = time.time()
initial_lobby_confirmed = False
in_game_reached = False
result_handled = False
cycle_complete = False
while time.time() - start_time < timeout_sec:
frame = bot.wm.capture_frame(client_only=True)
# 1. Global offer popup check
if bot.check_and_dismiss_offer_popup(frame):
time.sleep(1.0)
continue
state = bot.detect_state(frame)
if state != bot.state:
logging.info(f"[FSM TRANSITION] {bot.state.value} -> {state.value}")
bot.state = state
if state == GameState.TOWER_LOBBY:
if not initial_lobby_confirmed:
logging.info("[STEP 1] Confirmed TOWER_LOBBY start.")
initial_lobby_confirmed = True
bot.handle_lobby(frame)
elif in_game_reached and result_handled:
logging.info("[SUCCESS] Successfully completed full cycle and returned to TOWER_LOBBY!")
cycle_complete = True
break
else:
# If we are still in lobby before entering game, try handle_lobby again
bot.handle_lobby(frame)
elif state == GameState.IN_GAME:
in_game_reached = True
bot.handle_in_game(frame)
elif state == GameState.VICTORY_SCREEN:
logging.info("[STEP] Handling VICTORY_SCREEN...")
bot.handle_victory(frame)
result_handled = True
elif state == GameState.DEFEAT_SCREEN:
logging.info("[STEP] Handling DEFEAT_SCREEN...")
bot.handle_defeat(frame)
result_handled = True
elif state == GameState.NO_FREE_SLOTS_SCREEN:
logging.info("[STEP] Handling NO_FREE_SLOTS_SCREEN...")
bot.handle_no_free_slots(frame)
result_handled = True
elif state == GameState.CHEST_OPEN_SCREEN:
logging.info("[STEP] Handling CHEST_OPEN_SCREEN...")
bot.handle_chest_open_screen(frame)
elif state == GameState.MAIN_MENU:
logging.info("[STEP] Handling MAIN_MENU...")
bot.handle_main_menu(frame)
time.sleep(bot.poll_interval)
elapsed = time.time() - start_time
if cycle_complete:
logging.info(f"=== FULL CYCLE TEST PASSED in {elapsed:.1f}s ===")
return True
else:
logging.warning(f"=== TEST TIMEOUT or INTERRUPTED after {elapsed:.1f}s ===")
return False
if __name__ == "__main__":
run_single_cycle_test()