@@ -594,4 +594,70 @@ if success and dpAPI.isVersionCompatible(1) then
594594 })
595595end
596596
597+ -- ==========================================================================
598+ -- Completion Conditions
599+ -- ==========================================================================
600+
601+ -- The threshold for determining when game state transitions are complete.
602+ -- This value represents the maximum number of events allowed in the game's event queue
603+ -- to consider the game idle and waiting for user action. When the queue has fewer than
604+ -- 3 events, the game is considered stable enough to process API responses. This is a
605+ -- heuristic based on empirical testing to ensure smooth gameplay without delays.
606+ local EVENT_QUEUE_THRESHOLD = 3
607+
608+ --- Completion conditions for different game actions to determine when action execution is complete
609+ --- These are shared between API and LOG systems to ensure consistent timing
610+ --- @type table<string , function>
611+ utils .COMPLETION_CONDITIONS = {
612+ go_to_menu = function ()
613+ return G .STATE == G .STATES .MENU and G .MAIN_MENU_UI
614+ end ,
615+
616+ start_run = function ()
617+ return G .STATE == G .STATES .BLIND_SELECT
618+ and G .GAME .blind_on_deck
619+ and # G .E_MANAGER .queues .base < EVENT_QUEUE_THRESHOLD
620+ end ,
621+
622+ skip_or_select_blind = function ()
623+ -- Check if we're selecting a blind (facing_blind is set)
624+ if G .GAME and G .GAME .facing_blind and G .STATE == G .STATES .SELECTING_HAND then
625+ return true
626+ end
627+ -- Check if we skipped a blind (any blind is marked as "Skipped")
628+ if G .prev_small_state == " Skipped" or G .prev_large_state == " Skipped" or G .prev_boss_state == " Skipped" then
629+ return # G .E_MANAGER .queues .base < EVENT_QUEUE_THRESHOLD
630+ end
631+ return false
632+ end ,
633+
634+ play_hand_or_discard = function ()
635+ if # G .E_MANAGER .queues .base < EVENT_QUEUE_THRESHOLD and G .STATE_COMPLETE then
636+ -- round still going
637+ if G .buttons and G .STATE == G .STATES .SELECTING_HAND then
638+ return true
639+ -- round won and entering cash out state (ROUND_EVAL state)
640+ elseif G .STATE == G .STATES .ROUND_EVAL then
641+ return true
642+ -- game over state
643+ elseif G .STATE == G .STATES .GAME_OVER then
644+ return true
645+ end
646+ end
647+ return false
648+ end ,
649+
650+ rearrange_hand = function ()
651+ return G .STATE == G .STATES .SELECTING_HAND and # G .E_MANAGER .queues .base < EVENT_QUEUE_THRESHOLD and G .STATE_COMPLETE
652+ end ,
653+
654+ cash_out = function ()
655+ return G .STATE == G .STATES .SHOP and # G .E_MANAGER .queues .base < EVENT_QUEUE_THRESHOLD and G .STATE_COMPLETE
656+ end ,
657+
658+ shop = function ()
659+ return G .STATE == G .STATES .BLIND_SELECT and # G .E_MANAGER .queues .base < EVENT_QUEUE_THRESHOLD and G .STATE_COMPLETE
660+ end ,
661+ }
662+
597663return utils
0 commit comments